// 版权所有2009 Go作者。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

package reflect

import (
	"errors"
	"internal/abi"
	"internal/goarch"
	"internal/itoa"
	"internal/unsafeheader"
	"math"
	"runtime"
	"unsafe"
)

// 值是Go值的反射接口。
// 
// 并非所有方法都适用于所有类型的值。每种方法的文档中都注明了限制条件，如有。
// 在调用特定于种类的方法之前，请使用Kind方法找出值的种类。调用不适合该类型的方法
// 会导致运行时死机。
// 
// 零值表示没有值。
// 其IsValid方法返回false，其Kind方法返回Invalid，
// 其String方法返回“<Invalid Value>”，所有其他方法都死机。
// 大多数函数和方法从不返回无效值。
// 如果有，其文档会明确说明条件。
// 
// 如果
// 基础Go值可同时用于等效的
// 直接操作，则一个值可由多个Goroutine同时使用。要比较两个值，请比较接口方法的结果。
// 在两个值上使用==不会比较它们所代表的基础值
// 。
type Value struct {
	// typ保存由值表示的值的类型。
	typ *rtype

	// 指针值数据，如果设置了flagIndir，则为指向数据的指针。
	// 设置flagIndir或typ时有效。指针（）是真的。
	ptr unsafe.Pointer

	// 标志保存有关该值的元数据。
	// 最低位为标志位：
	// /-flagStickyRO:通过未报告的非嵌入字段获取，因此只读
	// /-Flagmedro:通过未报告的嵌入字段获取，因此只读
	// /-flagIndir:val持有指向数据的指针
	// /-flagAddr:v.CanAddr为true（暗示flagIndir）
	// /-flagMethod:v是一个方法值。
	// 接下来的五位给出了值的类型。
	// 这重复了典型。Kind（）方法值除外。
	// 剩余的23+位给出了方法值的方法编号。
	// If标志。善良的Func，代码可以假定flagMethod未设置。
	// 如果ifaceIndir（典型），则代码可以假定已设置flagIndir。
	flag

	// 方法值表示当前的方法调用
	// 类似r。读取某些接收器r。typ+val+标志位描述
	// 接收器r，但标志的种类位表示Func（方法是
	// 函数），标志的顶部位给出r的类型的方法表中的方法号
	// 。
}

type flag uintptr

const (
	flagKindWidth        = 5 // 共有27种
	flagKindMask    flag = 1<<flagKindWidth - 1
	flagStickyRO    flag = 1 << 5
	flagEmbedRO     flag = 1 << 6
	flagIndir       flag = 1 << 7
	flagAddr        flag = 1 << 8
	flagMethod      flag = 1 << 9
	flagMethodShift      = 10
	flagRO          flag = flagStickyRO | flagEmbedRO
)

func (f flag) kind() Kind {
	return Kind(f & flagKindMask)
}

func (f flag) ro() flag {
	if f&flagRO != 0 {
		return flagStickyRO
	}
	return 0
}

// pointer返回由v表示的基础指针。
// v.Kind（）必须是pointer、Map、Chan、Func或UnsafePointer 
// 如果v.Kind（）=pointer，则基类型不能是go:notinheap。
func (v Value) pointer() unsafe.Pointer {
	if v.typ.size != goarch.PtrSize || !v.typ.pointers() {
		panic("can't call pointer on a non-pointer Value")
	}
	if v.flag&flagIndir != 0 {
		return *(*unsafe.Pointer)(v.ptr)
	}
	return v.ptr
}

// packEface将v转换为空接口。
func packEface(v Value) any {
	t := v.typ
	var i any
	e := (*emptyInterface)(unsafe.Pointer(&i))
	// 首先，填写接口的数据部分。
	switch {
	case ifaceIndir(t):
		if v.flag&flagIndir == 0 {
			panic("bad indir")
		}
		// 值是间接的，我们正在制作的接口也是间接的。
		ptr := v.ptr
		if v.flag&flagAddr != 0 {
			// TODO:从valueInterface传递安全布尔值，所以
			// 如果safe==true，我们不需要复制？
			c := unsafe_New(t)
			typedmemmove(t, c, ptr)
			ptr = c
		}
		e.word = ptr
	case v.flag&flagIndir != 0:
		// 值是间接的，但接口是直接的。我们需要
		// 将v.ptr上的数据加载到接口数据字中。
		e.word = *(*unsafe.Pointer)(v.ptr)
	default:
		// 值是直接的，接口也是直接的。
		e.word = v.ptr
	}
	// 现在，填写类型部分。我们在这里非常小心，不要在e.word和e.typ赋值之间进行任何操作，这会让垃圾收集器观察部分构建的
	// 接口值。
	e.typ = t
	return i
}

// Unpreface将空接口i转换为值。
func unpackEface(i any) Value {
	e := (*emptyInterface)(unsafe.Pointer(&i))
	// 注意：在我们知道e.word是否真的是指针之前，不要阅读它。
	t := e.typ
	if t == nil {
		return Value{}
	}
	f := flag(t.Kind())
	if ifaceIndir(t) {
		f |= flagIndir
	}
	return Value{t, e.word, f}
}

// 在
// 不支持Value方法的值上调用Value方法时，会发生Value错误。在每种方法的描述中，都记录了这种情况。
type ValueError struct {
	Method string
	Kind   Kind
}

func (e *ValueError) Error() string {
	if e.Kind == 0 {
		return "reflect: call of " + e.Method + " on zero Value"
	}
	return "reflect: call of " + e.Method + " on " + e.Kind.String() + " Value"
}

// methodName返回调用方法的名称，
// 假定为上面的两个堆栈帧。
func methodName() string {
	pc, _, _, _ := runtime.Caller(2)
	f := runtime.FuncForPC(pc)
	if f == nil {
		return "unknown method"
	}
	return f.Name()
}

// methodNameSkip类似于methodName，但跳过另一个堆栈帧。
// 这是一个单独的函数，以便反映。旗帜mustBe将被内联。
func methodNameSkip() string {
	pc, _, _, _ := runtime.Caller(3)
	f := runtime.FuncForPC(pc)
	if f == nil {
		return "unknown method"
	}
	return f.Name()
}

// emptyInterface是接口{}值的头。
type emptyInterface struct {
	typ  *rtype
	word unsafe.Pointer
}

// nonEmptyInterface是带有方法的接口值的头。
type nonEmptyInterface struct {
	// 看/运行时/iface。go:/Itab 
	itab *struct {
		ityp *rtype // 静态接口类型
		typ  *rtype // 动态混凝土类型
		hash uint32 // 类型副本。hash 
		_    [4]byte
		fun  [100000]unsafe.Pointer // 方法表
	}
	word unsafe.Pointer
}

// 如果不需要f的种类，则必须是恐慌。
// 将此方法设置为flag而不是Value方法
// （并将flag嵌入Value）意味着我们可以编写
// 非常清晰的v.mustBe（Bool）并将其编译为
// v.flag。mustBe（Bool），它只需要为接收者复制
// 一个重要的单词。
func (f flag) mustBe(expected Kind) {
	// TODO（mvdan）：如果f记录值是使用
	if Kind(f&flagKindMask) != expected {
		panic(&ValueError{methodName(), f.kind()})
	}
}

// 未报告的字段获得的，则再次使用f.kind（），使堆栈中的内联变得更好。
func (f flag) mustBeExported() {
	if f == 0 || f&flagRO != 0 {
		f.mustBeExportedSlow()
	}
}

func (f flag) mustBeExportedSlow() {
	if f == 0 {
		panic(&ValueError{methodNameSkip(), Invalid})
	}
	if f&flagRO != 0 {
		panic("reflect: " + methodNameSkip() + " using value obtained using unexported field")
	}
}

// 如果f记录该值不可分配，则必须为可分配的恐慌，也就是说，该值要么是使用未报告的字段
// 获得的，要么是不可寻址的。
func (f flag) mustBeAssignable() {
	if f&flagRO != 0 || f&flagAddr == 0 {
		f.mustBeAssignableSlow()
	}
}

func (f flag) mustBeAssignableSlow() {
	if f == 0 {
		panic(&ValueError{methodNameSkip(), Invalid})
	}
	// 如果可寻址且非只读，则可分配。
	if f&flagRO != 0 {
		panic("reflect: " + methodNameSkip() + " using value obtained using unexported field")
	}
	if f&flagAddr == 0 {
		panic("reflect: " + methodNameSkip() + " using unaddressable value")
	}
}

// Addr返回一个表示v的地址的指针值。
// 如果CanAddr（）返回false，它将崩溃。
// Addr通常用于获取指向结构字段
// 或切片元素的指针，以便调用需要
// 指针接收器的方法。
func (v Value) Addr() Value {
	if v.flag&flagAddr == 0 {
		panic("reflect.Value.Addr of unaddressable value")
	}
	// 保留flagRO而不是使用v.flag。所以
	// v.Addr（）。Elem（）相当于v（#32772）
	fl := v.flag & flagRO
	return Value{v.typ.ptrTo(), v.ptr, fl | flag(Pointer)}
}

// Bool返回v的基础值。
// 如果v的类型不是布尔，它会恐慌。
func (v Value) Bool() bool {
	v.mustBe(Bool)
	return *(*bool)(v.ptr)
}

// 字节返回v的基础值。
// 如果v的底层值不是字节片，它就会恐慌。
func (v Value) Bytes() []byte {
	v.mustBe(Slice)
	if v.typ.Elem().Kind() != Uint8 {
		panic("reflect.Value.Bytes of non-byte slice")
	}
	// 切片总是比一个单词大；假设是flagIndir。
	return *(*[]byte)(v.ptr)
}

// 符文返回v的基础值。
// 如果v的基本值不是一段符文（int32s），它就会恐慌。
func (v Value) runes() []rune {
	v.mustBe(Slice)
	if v.typ.Elem().Kind() != Int32 {
		panic("reflect.Value.Bytes of non-rune slice")
	}
	// 切片总是大于一个单词；假设是flagIndir。
	return *(*[]rune)(v.ptr)
}

// CanAddr报告是否可以通过Addr获取值的地址。
// 这样的值称为可寻址。如果值是
// 一个片的元素、一个可寻址数组的元素、
// 一个可寻址结构的字段，或者是取消引用指针的结果，则该值是可寻址的。
// 如果CanAddr返回false，调用Addr将导致恐慌。
func (v Value) CanAddr() bool {
	return v.flag&flagAddr != 0
}

// CanSet报告v的值是否可以更改。
// 只有当值可寻址且不是通过使用未报告的结构字段获得的
// 时，才能更改该值。
// 如果CanSet返回false，调用Set或任何特定于类型的
// setter（例如SetBool、SetInt）将死机。
func (v Value) CanSet() bool {
	return v.flag&(flagAddr|flagRO) == flagAddr
}

// Call使用中的输入参数调用函数v。
// 例如，如果len（in）=3，那么v.Call（in）代表Go Call v（in[0]、[1]、[2]）。
// 如果v的类型不正常，则呼叫恐慌。
// 它以值的形式返回输出结果。
// 与Go一样，每个输入参数必须可分配给函数对应输入参数的
// 类型。
// 如果v是一个可变函数，Call将创建可变切片参数
// 本身，并复制相应的值。
func (v Value) Call(in []Value) []Value {
	v.mustBe(Func)
	v.mustBeExported()
	return v.call("Call", in)
}

// CallSlice使用中的输入参数调用变量函数v，
// 将[len（in）-1]中的切片指定给v的最终变量参数。
// 例如，如果len（in）=3，那么v.CallSlice（in）代表Go call v（在[0]、[1]、[2]…）。
// 如果v的种类不是Func或如果v不是可变的，则调用片恐慌。
// 它以值的形式返回输出结果。
// 与Go一样，每个输入参数都必须可分配给函数相应输入参数的
// 类型。
func (v Value) CallSlice(in []Value) []Value {
	v.mustBe(Func)
	v.mustBeExported()
	return v.call("CallSlice", in)
}

var callGC bool // 用于测试；请参阅TestCallMethodJump和TestCallArgLive 

const debugReflectCall = false

func (v Value) call(op string, in []Value) []Value {
	// 获取函数指针，键入。
	t := (*funcType)(unsafe.Pointer(v.typ))
	var (
		fn       unsafe.Pointer
		rcvr     Value
		rcvrtype *rtype
	)
	if v.flag&flagMethod != 0 {
		rcvr = v
		rcvrtype, t, fn = methodReceiver(op, v, int(v.flag)>>flagMethodShift)
	} else if v.flag&flagIndir != 0 {
		fn = *(*unsafe.Pointer)(v.ptr)
	} else {
		fn = v.ptr
	}

	if fn == nil {
		panic("reflect.Value.Call: call of nil function")
	}

	isSlice := op == "CallSlice"
	n := t.NumIn()
	isVariadic := t.IsVariadic()
	if isSlice {
		if !isVariadic {
			panic("reflect: CallSlice of non-variadic function")
		}
		if len(in) < n {
			panic("reflect: CallSlice with too few input arguments")
		}
		if len(in) > n {
			panic("reflect: CallSlice with too many input arguments")
		}
	} else {
		if isVariadic {
			n--
		}
		if len(in) < n {
			panic("reflect: Call with too few input arguments")
		}
		if !isVariadic && len(in) > n {
			panic("reflect: Call with too many input arguments")
		}
	}
	for _, x := range in {
		if x.Kind() == Invalid {
			panic("reflect: " + op + " using zero Value argument")
		}
	}
	for i := 0; i < n; i++ {
		if xt, targ := in[i].Type(), t.In(i); !xt.AssignableTo(targ) {
			panic("reflect: " + op + " using " + xt.String() + " as type " + targ.String())
		}
	}
	if !isSlice && isVariadic {
		// 为剩余值准备切片
		m := len(in) - n
		slice := MakeSlice(t.In(n), m, m)
		elem := t.In(n).Elem()
		for i := 0; i < m; i++ {
			x := in[n+i]
			if xt := x.Type(); !xt.AssignableTo(elem) {
				panic("reflect: cannot use " + xt.String() + " as type " + elem.String() + " in " + op)
			}
			slice.Index(i).Set(x)
		}
		origIn := in
		in = make([]Value, n+1)
		copy(in[:n], origIn)
		in[n] = slice
	}

	nin := len(in)
	if nin != t.NumIn() {
		panic("reflect.Value.Call: wrong argument count")
	}
	nout := t.NumOut()

	// 寄存器参数空间。
	var regArgs abi.RegArgs

	// 计算帧类型。
	frametype, framePool, abi := funcLayout(t, rcvrtype)

	// 如果需要，为帧分配一块内存。
	var stackArgs unsafe.Pointer
	if frametype.size != 0 {
		if nout == 0 {
			stackArgs = framePool.Get().(unsafe.Pointer)
		} else {
			// 如果函数有返回值，则无法使用池。
			// 我们将在ret中泄漏指向args的指针，因此它的生存期不受限制。
			stackArgs = unsafe_New(frametype)
		}
	}
	frameSize := frametype.size

	if debugReflectCall {
		println("reflect.call", t.String())
		abi.dump()
	}

	// 将输入复制到args中。

	// 手柄接收器。
	inStart := 0
	if rcvrtype != nil {
		// 保证只有一个字的大小，
		// 所以它只需要1个字节（在寄存器或堆栈中）。
		switch st := abi.call.steps[0]; st.kind {
		case abiStepStack:
			storeRcvr(rcvr, stackArgs)
		case abiStepIntReg, abiStepPointer:
			// 甚至指针也可以进入uintptr插槽，因为
			// 它们将被
			// 这个框架。反射迫使它们被堆分配，所以我们不需要担心堆栈复制。
			storeRcvr(rcvr, unsafe.Pointer(&regArgs.Ints[st.ireg]))
		case abiStepFloatReg:
			storeRcvr(rcvr, unsafe.Pointer(&regArgs.Floats[st.freg]))
		default:
			panic("unknown ABI parameter kind")
		}
		inStart = 1
	}

	// 处理参数。
	for i, v := range in {
		v.mustBeExported()
		targ := t.In(i).(*rtype)
		// TODO（mknyszek）：找出是否有可能获得一些
		// 用于此任务检查的临时空间。在此之前，
		// 可以在参数框中使用空格。
		v = v.assignTo("reflect.Value.Call", targ, nil)
	stepsLoop:
		for _, st := range abi.call.stepsForValue(i + inStart) {
			switch st.kind {
			case abiStepStack:
				// 将值复制到“堆栈”
				addr := add(stackArgs, st.stkOff, "precomputed stack arg offset")
				if v.flag&flagIndir != 0 {
					typedmemmove(targ, addr, v.ptr)
				} else {
					*(*unsafe.Pointer)(addr) = v.ptr
				}
				// 堆栈分配值只有一个步骤。
				break stepsLoop
			case abiStepIntReg, abiStepPointer:
				// 将值复制到“整数寄存器”
				if v.flag&flagIndir != 0 {
					offset := add(v.ptr, st.offset, "precomputed value offset")
					if st.kind == abiStepPointer {
						// 在
						// 寄存器空间的指针区域复制此指针。否则，
						// 这可能是对v.ptr的最后一次引用。
						regArgs.Ptrs[st.ireg] = *(*unsafe.Pointer)(offset)
					}
					intToReg(&regArgs, st.ireg, st.size, offset)
				} else {
					if st.kind == abiStepPointer {
						// 请参见上述案例中的注释。
						regArgs.Ptrs[st.ireg] = v.ptr
					}
					regArgs.Ints[st.ireg] = uintptr(v.ptr)
				}
			case abiStepFloatReg:
				// 将值复制到“浮点寄存器”
				if v.flag&flagIndir == 0 {
					panic("attempted to copy pointer to FP register")
				}
				offset := add(v.ptr, st.offset, "precomputed value offset")
				floatToReg(&regArgs, st.freg, st.size, offset)
			default:
				panic("unknown ABI part kind")
			}
		}
	}
	// TODO（mknyszek）：当我们不再有
	// 呼叫方保留的溢出空间时，请删除此选项。
	frameSize = align(frameSize, goarch.PtrSize)
	frameSize += abi.spill

	// 在寄存器中为返回路径标记指针。
	regArgs.ReturnIsPtr = abi.outRegPtrs

	if debugReflectCall {
		regArgs.Dump()
	}

	// 用于测试；请看TestCallArgLive。
	if callGC {
		runtime.GC()
	}

	// 打电话。
	call(frametype, fn, stackArgs, uint32(frametype.size), uint32(abi.retOffset), uint32(frameSize), &regArgs)

	// 用于测试；请参阅TestCallMethodJump。
	if callGC {
		runtime.GC()
	}

	var ret []Value
	if nout == 0 {
		if stackArgs != nil {
			typedmemclr(frametype, stackArgs)
			framePool.Put(stackArgs)
		}
	} else {
		if stackArgs != nil {
			// 将当前未使用的args输入区域，
			// 归零，因为此函数返回的值包含指向args对象的指针，
			// 因此将使args对象无限期地保持活动状态。
			typedmemclrpartial(frametype, stackArgs, 0, abi.retOffset)
		}

		// 在args中围绕返回值包装值。
		ret = make([]Value, nout)
		for i := 0; i < nout; i++ {
			tv := t.Out(i)
			if tv.Size() == 0 {
				// 对于大小为零的返回值，args+off可能指向下一个对象。
				// 在这种情况下，返回零值。
				ret[i] = Zero(tv)
				continue
			}
			steps := abi.ret.stepsForValue(i)
			if st := steps[0]; st.kind == abiStepStack {
				// 此值位于堆栈上。如果一个值的一部分是stack 
				// allocated，那么整个值都是根据ABI的。所以
				// 只需对分配的帧进行间接寻址。
				fl := flagIndir | flag(tv.Kind())
				ret[i] = Value{tv.common(), add(stackArgs, st.stkOff, "tv.Size() != 0"), fl}
				// 注意：这确实会在结果之间引入错误共享-
				// 如果任何结果是实时的，它们都是实时的。
				// （args的空间也是实时的，但正如我们已经清除了这个空间一样，这没什么大不了的。）
				continue
			}

			// 处理在寄存器中传递的指针。
			if !ifaceIndir(tv.common()) {
				// 指针值数据直接放入v.ptr。
				if steps[0].kind != abiStepPointer {
					print("kind=", steps[0].kind, ", type=", tv.String(), "\n")
					panic("mismatch between ABI description and types")
				}
				ret[i] = Value{tv.common(), regArgs.Ptrs[steps[0].ireg], flag(tv.Kind())}
				continue
			}

			// 剩下的就是在寄存器中传递的值，我们需要这些值来创建空间并将值复制回寄存器中。
			// 
			// TODO（mknyszek）：我们为分配给
			// 值的每个寄存器进行新的分配，但之前我们总是可以指向堆分配的
			// 堆栈帧。这是一个回归，可以通过将
			// 额外空间添加到分配的堆栈帧中，并将
			// 寄存器分配的返回值存储到分配的堆栈帧中，以及
			// 在结果值中引用来修复。
			s := unsafe_New(tv.common())
			for _, st := range steps {
				switch st.kind {
				case abiStepIntReg:
					offset := add(s, st.offset, "precomputed value offset")
					intFromReg(&regArgs, st.ireg, st.size, offset)
				case abiStepPointer:
					s := add(s, st.offset, "precomputed value offset")
					*((*unsafe.Pointer)(s)) = regArgs.Ptrs[st.ireg]
				case abiStepFloatReg:
					offset := add(s, st.offset, "precomputed value offset")
					floatFromReg(&regArgs, st.freg, st.size, offset)
				case abiStepStack:
					panic("register-based return value has stack component")
				default:
					panic("unknown ABI part kind")
				}
			}
			ret[i] = Value{tv.common(), s, flagIndir | flag(tv.Kind())}
		}
	}

	return ret
}

// callReflect是MakeFunc返回的函数
// 使用的调用实现。在许多方面，它与
// 方法值相反。给上面打电话。上述方法将使用值
// 的调用转换为具有具体参数帧的函数调用，而
// callReflect将具有具体参数
// 帧的函数调用转换为使用值的调用。
// 它在这个文件中，所以它可以位于上面的调用方法旁边。
// MakeFunc实现的其余部分在MakeFunc中。去
// 
// 注意：此函数必须在生成的代码
// 中标记为“包装器”，以便链接器可以使其正常工作，以防死机和恢复。
// gc编译器知道为了“reflect.callReflect”这个名字而这样做。
// 
// ctxt是MakeFunc生成的“闭包”。
// frame是指向堆栈上该闭包的参数的指针。
// retValid指向一个布尔值，当设置结果
// 帧的部分时，应该设置该布尔值。
// 
// regs包含在寄存器中传递的参数值，并将包含
// 从ctxt返回的值。fn在寄存器中。
func callReflect(ctxt *makeFuncImpl, frame unsafe.Pointer, retValid *bool, regs *abi.RegArgs) {
	if callGC {
		// 在测试过程中输入时调用GC。
		// 在这里扫描堆栈是最大的危险，因为
		// 我们的调用方（Makefunstub）可能无法将最后一个
		// 指针放置到regs的指针空间中的值，在这种情况下，它对GC不可见。
		runtime.GC()
	}
	ftyp := ctxt.ftyp
	f := ctxt.fn

	_, _, abi := funcLayout(ftyp, nil)

	// 将参数复制到值中。
	ptr := frame
	in := make([]Value, 0, int(ftyp.inCount))
	for i, typ := range ftyp.in() {
		if typ.Size() == 0 {
			in = append(in, Zero(typ))
			continue
		}
		v := Value{typ, nil, flag(typ.Kind())}
		steps := abi.call.stepsForValue(i)
		if st := steps[0]; st.kind == abiStepStack {
			if ifaceIndir(typ) {
				// 接口数据中不能内联值。
				// 必须复制，因为f可能会保留对它的引用，
				// 在该函数返回后，我们不能让f保留对堆栈帧
				// 的引用，甚至不能保留只读引用。
				v.ptr = unsafe_New(typ)
				if typ.size > 0 {
					typedmemmove(typ, v.ptr, add(ptr, st.stkOff, "typ.size > 0"))
				}
				v.flag |= flagIndir
			} else {
				v.ptr = *(*unsafe.Pointer)(add(ptr, st.stkOff, "1-ptr"))
			}
		} else {
			if ifaceIndir(typ) {
				// 剩下的就是在寄存器中传递的值，我们需要这些值来为这些值创建空间。
				v.flag |= flagIndir
				v.ptr = unsafe_New(typ)
				for _, st := range steps {
					switch st.kind {
					case abiStepIntReg:
						offset := add(v.ptr, st.offset, "precomputed value offset")
						intFromReg(regs, st.ireg, st.size, offset)
					case abiStepPointer:
						s := add(v.ptr, st.offset, "precomputed value offset")
						*((*unsafe.Pointer)(s)) = regs.Ptrs[st.ireg]
					case abiStepFloatReg:
						offset := add(v.ptr, st.offset, "precomputed value offset")
						floatFromReg(regs, st.freg, st.size, offset)
					case abiStepStack:
						panic("register-based return value has stack component")
					default:
						panic("unknown ABI part kind")
					}
				}
			} else {
				// 指针值数据直接放入v.ptr。
				if steps[0].kind != abiStepPointer {
					print("kind=", steps[0].kind, ", type=", typ.String(), "\n")
					panic("mismatch between ABI description and types")
				}
				v.ptr = regs.Ptrs[steps[0].ireg]
			}
		}
		in = append(in, v)
	}

	// 调用底层函数。
	out := f(in)
	numOut := ftyp.NumOut()
	if len(out) != numOut {
		panic("reflect: wrong return count from function created by MakeFunc")
	}

	// 将结果复制回参数帧和寄存器空间。
	if numOut > 0 {
		for i, typ := range ftyp.out() {
			v := out[i]
			if v.typ == nil {
				panic("reflect: function created by MakeFunc using " + funcName(f) +
					" returned zero Value")
			}
			if v.flag&flagRO != 0 {
				panic("reflect: function created by MakeFunc using " + funcName(f) +
					" returned value obtained from unexported field")
			}
			if typ.size == 0 {
				continue
			}

			// 如果v可分配给语言规范中t类型的变量
			// 则将v转换为type typ。
			// 请参阅第28761期。
			// 
			// 
			// TODO（mknyszek）：在切换到寄存器ABI的过程中，我们丢失了
			// 寄存器案例的暂存空间（所有案例的暂存空间为
			// ）。
			// 
			// 如果发生这种情况，请注意以下事项：
			// 
			// 我们必须在调用assignTo之前清除目标，
			// 以防assignTo写入
			// 目标位置用作暂存空间。见第39541期。
			v = v.assignTo("reflect.MakeFunc", typ, nil)
		stepsLoop:
			for _, st := range abi.ret.stepsForValue(i) {
				switch st.kind {
				case abiStepStack:
					// 将值复制到“堆栈”
					addr := add(ptr, st.stkOff, "precomputed stack arg offset")
					// 不要使用写屏障。
					// 用于此调用的堆栈空间没有充分归零，我们
					// 在返回Makefunstub的调用者之前，会小心地保持参数处于活动状态。
					if v.flag&flagIndir != 0 {
						memmove(addr, v.ptr, st.size)
					} else {
						// 此大小写必须是指针类型。
						*(*uintptr)(addr) = uintptr(v.ptr)
					}
					// 堆栈分配值只有一个步骤。
					break stepsLoop
				case abiStepIntReg, abiStepPointer:
					// 将值复制到“整数寄存器”
					if v.flag&flagIndir != 0 {
						offset := add(v.ptr, st.offset, "precomputed value offset")
						intToReg(regs, st.ireg, st.size, offset)
					} else {
						// 只填充返回路径上的Ints空间。
						// 这是安全的，因为out一直保持活动状态，直到
						// 此函数结束，并且通过
						// Makefunstub的返回路径没有抢占权，所以这些指针
						// 始终对GC可见。
						regs.Ints[st.ireg] = uintptr(v.ptr)
					}
				case abiStepFloatReg:
					// 将值复制到“浮点寄存器”
					if v.flag&flagIndir == 0 {
						panic("attempted to copy pointer to FP register")
					}
					offset := add(v.ptr, st.offset, "precomputed value offset")
					floatToReg(regs, st.freg, st.size, offset)
				default:
					panic("unknown ABI part kind")
				}
			}
		}
	}

	// 宣布返回值有效。
	// 在这一点之后，运行时可以依赖于有效的返回值。
	*retValid = true

	// 我们必须确保out片至少在运行时知道返回值有效之前一直有效。否则，在GC期间，任何人都可能不会扫描
	// 返回值。
	// （out将是死的，返回槽还没有激活。）
	runtime.KeepAlive(out)

	// 运行时。getArgInfo希望在找到调用程序Makefunstub时，能够在
	// 堆栈上找到ctxt。确保它
	// 不会被垃圾收集。
	runtime.KeepAlive(ctxt)
}

// methodReceiver返回关于v描述的接收器
// 的信息。值v可能有也可能没有设置
// flagMethod位，因此应该不使用v.flag中缓存的类型
// 。
// 返回值rcvrtype给出了方法的实际接收器类型。
// 返回值t给出方法类型签名（不带接收方）。
// 返回值fn是指向方法代码的指针。
func methodReceiver(op string, v Value, methodIndex int) (rcvrtype *rtype, t *funcType, fn unsafe.Pointer) {
	i := methodIndex
	if v.typ.Kind() == Interface {
		tt := (*interfaceType)(unsafe.Pointer(v.typ))
		if uint(i) >= uint(len(tt.methods)) {
			panic("reflect: internal error: invalid method index")
		}
		m := &tt.methods[i]
		if !tt.nameOff(m.name).isExported() {
			panic("reflect: " + op + " of unexported method")
		}
		iface := (*nonEmptyInterface)(v.ptr)
		if iface.itab == nil {
			panic("reflect: " + op + " of method on nil interface value")
		}
		rcvrtype = iface.itab.typ
		fn = unsafe.Pointer(&iface.itab.fun[i])
		t = (*funcType)(unsafe.Pointer(tt.typeOff(m.typ)))
	} else {
		rcvrtype = v.typ
		ms := v.typ.exportedMethods()
		if uint(i) >= uint(len(ms)) {
			panic("reflect: internal error: invalid method index")
		}
		m := ms[i]
		if !v.typ.nameOff(m.name).isExported() {
			panic("reflect: " + op + " of unexported method")
		}
		ifn := v.typ.textOff(m.ifn)
		fn = unsafe.Pointer(&ifn)
		t = (*funcType)(unsafe.Pointer(v.typ.typeOff(m.mtyp)))
	}
	return
}

// v是一个方法接收器。将用于
// 对参数列表开头的接收器进行编码的单词存储在p处。
// Reflect对
// 方法使用“接口”调用约定，它总是使用一个字来记录接收方。
func storeRcvr(v Value, p unsafe.Pointer) {
	t := v.typ
	if t.Kind() == Interface {
		// 接口数据字变为接收字
		iface := (*nonEmptyInterface)(v.ptr)
		*(*unsafe.Pointer)(p) = iface.word
	} else if v.flag&flagIndir != 0 && !ifaceIndir(t) {
		*(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(v.ptr)
	} else {
		*(*unsafe.Pointer)(p) = v.ptr
	}
}

// align返回将x取整为n的倍数的结果。
// n必须是2的幂。
func align(x, n uintptr) uintptr {
	return (x + n - 1) &^ (n - 1)
}

// callMethod是由makeMethodValue返回的函数
// （由v.Method（i）使用）使用的调用实现。接口（））。
// 这是通常的reflect调用的简化版本：调用者已经为我们列出了参数框架，所以我们没有
// 来处理每个参数的单个值。
// 它在这个文件中，因此它可以位于上面两个类似函数的旁边。
// makeMethodValue实现的其余部分在makefunc中。去
// 
// 注意：在生成的代码
// 中，必须将此函数标记为“包装器”，以便链接器可以使其正常工作，以防死机和恢复。
// gc编译器知道为了“reflect.callMethod”这个名字而这样做。
// 
// ctxt是makeVethodValue生成的“闭包”。
// frame是指向堆栈上该闭包的参数的指针。
// retValid指向一个布尔值，当结果
// 设置了框架的截面。
// 
// regs包含在寄存器中传递的参数值，并将包含从ctxt返回的值。fn在寄存器中。
func callMethod(ctxt *methodValue, frame unsafe.Pointer, retValid *bool, regs *abi.RegArgs) {
	rcvr := ctxt.rcvr
	rcvrType, valueFuncType, methodFn := methodReceiver("call", rcvr, ctxt.method)

	// 这里有两个ABI。
	// 
	// methodValueCall是用ABI调用的，假设没有
	// receiver（“值ABI”），这就是帧和正则表达式所包含的内容。
	// 
	// 同时，我们需要实际使用接收方调用该方法，该接收方有自己的ABI（“方法ABI”）。以下是两者之间的翻译。
	_, _, valueABI := funcLayout(valueFuncType, nil)
	valueFrame, valueRegs := frame, regs
	methodFrameType, methodFramePool, methodABI := funcLayout(valueFuncType, rcvrType)

	// 制作一个新的帧，大一个字，这样我们就可以存储接收器。
	// 此空间用于参数和返回值。
	methodFrame := methodFramePool.Get().(unsafe.Pointer)
	var methodRegs abi.RegArgs

	// 处理接收者。保证只有一个字大小。
	if st := methodABI.call.steps[0]; st.kind == abiStepStack {
		// 只有在ABI同意的情况下，才能将接收器复制到堆栈中。
		// 否则，它已经在寄存器中了。
		storeRcvr(rcvr, methodFrame)
	} else {
		// 将接收器放入寄存器。
		storeRcvr(rcvr, unsafe.Pointer(&methodRegs.Ints))
	}

	// 翻译其余的论点。
	for i, t := range valueFuncType.in() {
		valueSteps := valueABI.call.stepsForValue(i)
		methodSteps := methodABI.call.stepsForValue(i + 1)

		// 零大小的类型很简单：无需操作。
		if len(valueSteps) == 0 {
			if len(methodSteps) != 0 {
				panic("method ABI and value ABI do not align")
			}
			continue
		}

		// 在翻译每个
		// 参数时需要处理四个案例：
		// 1。堆栈->堆栈转换。
		// 2。堆栈->寄存器转换。
		// 3。寄存器->堆栈转换。
		// 4。寄存器->寄存器转换。

		// 如果值ABI传递堆栈上的值，
		// 那么方法ABI也会传递，因为它的参数更少。简单地在两者之间复制。
		if vStep := valueSteps[0]; vStep.kind == abiStepStack {
			mStep := methodSteps[0]
			// 处理堆栈->堆栈转换。
			if mStep.kind == abiStepStack {
				if vStep.size != mStep.size {
					panic("method ABI and value ABI do not align")
				}
				typedmemmove(t,
					add(methodFrame, mStep.stkOff, "precomputed stack offset"),
					add(valueFrame, vStep.stkOff, "precomputed stack offset"))
				continue
			}
			// 句柄堆栈->寄存器转换。
			for _, mStep := range methodSteps {
				from := add(valueFrame, vStep.stkOff+mStep.offset, "precomputed stack offset")
				switch mStep.kind {
				case abiStepPointer:
					// 直接复制指针，这样我们就有了写障碍。
					methodRegs.Ptrs[mStep.ireg] = *(*unsafe.Pointer)(from)
					fallthrough // 我们需要确保这也会在Ints中结束。
				case abiStepIntReg:
					intToReg(&methodRegs, mStep.ireg, mStep.size, from)
				case abiStepFloatReg:
					floatToReg(&methodRegs, mStep.freg, mStep.size, from)
				default:
					panic("unexpected method step")
				}
			}
			continue
		}
		// 句柄寄存器->堆栈转换。
		if mStep := methodSteps[0]; mStep.kind == abiStepStack {
			for _, vStep := range valueSteps {
				to := add(methodFrame, mStep.stkOff+vStep.offset, "precomputed stack offset")
				switch vStep.kind {
				case abiStepPointer:
					// 直接复制指针，这样我们就有了写屏障。
					*(*unsafe.Pointer)(to) = valueRegs.Ptrs[vStep.ireg]
				case abiStepIntReg:
					intFromReg(valueRegs, vStep.ireg, vStep.size, to)
				case abiStepFloatReg:
					floatFromReg(valueRegs, vStep.freg, vStep.size, to)
				default:
					panic("unexpected value step")
				}
			}
			continue
		}
		// 处理寄存器->寄存器转换。
		if len(valueSteps) != len(methodSteps) {
			// 因为它的值的类型相同，并且两次都被分配给了
			// 寄存器，所以它应该始终占用相同的
			// 每个ABI的寄存器数量。
			panic("method ABI and value ABI don't align")
		}
		for i, vStep := range valueSteps {
			mStep := methodSteps[i]
			if mStep.kind != vStep.kind {
				panic("method ABI and value ABI don't align")
			}
			switch vStep.kind {
			case abiStepPointer:
				// 也复制这个，这样我们就有了写障碍。
				methodRegs.Ptrs[mStep.ireg] = valueRegs.Ptrs[vStep.ireg]
				fallthrough
			case abiStepIntReg:
				methodRegs.Ints[mStep.ireg] = valueRegs.Ints[vStep.ireg]
			case abiStepFloatReg:
				methodRegs.Floats[mStep.freg] = valueRegs.Floats[vStep.freg]
			default:
				panic("unexpected value step")
			}
		}
	}

	methodFrameSize := methodFrameType.size
	// TODO（mknyszek）：当我们不再有
	// 呼叫方保留的溢出空间时，请删除此选项。
	methodFrameSize = align(methodFrameSize, goarch.PtrSize)
	methodFrameSize += methodABI.spill

	// 在寄存器中为返回路径标记指针。
	methodRegs.ReturnIsPtr = methodABI.outRegPtrs

	// 打电话。
	// Call将参数从头复制到堆栈中，调用fn，
	// 然后将结果复制回scratch。
	call(methodFrameType, methodFn, methodFrame, uint32(methodFrameType.size), uint32(methodABI.retOffset), uint32(methodFrameSize), &methodRegs)

	// 复制返回值。
	// 
	// 这稍微简单一些，因为两个ABI都有相同的
	// 返回值ABI（类型相同）。因此，可以简单地复制寄存器
	// 结果。堆栈分配的值是相同的，但与帧开始的偏移量不同。忽略对参数的任何更改。
	// 如果没有返回值，请避免构造越界指针。
	// 因为论点可能会有不同的表述。
	if valueRegs != nil {
		*valueRegs = methodRegs
	}
	if retSize := methodFrameType.size - methodABI.retOffset; retSize > 0 {
		valueRet := add(valueFrame, valueABI.retOffset, "valueFrame's size > retOffset")
		methodRet := add(methodFrame, methodABI.retOffset, "methodFrame's size > retOffset")
		// 这会复制到堆栈中。不需要写障碍。
		memmove(valueRet, methodRet, retSize)
	}

	// 告诉运行时，它现在可以依赖于正确初始化的返回值
	// 了。
	*retValid = true

	// 清除划痕空间并将其放回池中。
	// 这必须在上面的语句之后发生，这样返回的
	// 值将始终被某人扫描。
	typedmemclr(methodFrameType, methodFrame)
	methodFramePool.Put(methodFrame)

	// 请参阅callReflect中的注释。wen jian defg
	runtime.KeepAlive(ctxt)

	// 调用者（methodValueCall）将其作为堆栈对象，只有当存在对它的引用时，才会对其进行扫描。
	runtime.KeepAlive(valueRegs)
}

// funcName返回f的名称，用于错误消息。
func funcName(f func([]Value) []Value) string {
	pc := *(*uintptr)(unsafe.Pointer(&f))
	rf := runtime.FuncForPC(pc)
	if rf != nil {
		return rf.Name()
	}
	return "closure"
}

// Cap返回v的容量。
// 如果v的种类不是数组、Chan或Slice，它会感到恐慌。
func (v Value) Cap() int {
	k := v.kind()
	switch k {
	case Array:
		return v.typ.Len()
	case Chan:
		return chancap(v.pointer())
	case Slice:
		// 切片总是比一个单词大；假设是flagIndir。
		return (*unsafeheader.Slice)(v.ptr).Cap
	}
	panic(&ValueError{"reflect.Value.Cap", v.kind()})
}

// 关闭频道v。
// 如果v的类型不是Chan，它会感到恐慌。
func (v Value) Close() {
	v.mustBe(Chan)
	v.mustBeExported()
	chanclose(v.pointer())
}

// CanComplex报告Complex是否可以在不惊慌的情况下使用。
func (v Value) CanComplex() bool {
	switch v.kind() {
	case Complex64, Complex128:
		return true
	default:
		return false
	}
}

// Complex以complex128的形式返回v的基础值。
// 如果v的种类不是Complex64或Complex128，它就会崩溃
func (v Value) Complex() complex128 {
	k := v.kind()
	switch k {
	case Complex64:
		return complex128(*(*complex64)(v.ptr))
	case Complex128:
		return *(*complex128)(v.ptr)
	}
	panic(&ValueError{"reflect.Value.Complex", v.kind()})
}

// Elem返回接口v包含的值
// 或指针v指向的。
// 如果v的种类不是接口或指针，它就会恐慌。
// 如果v为零，则返回零值。
func (v Value) Elem() Value {
	k := v.kind()
	switch k {
	case Interface:
		var eface any
		if v.typ.NumMethod() == 0 {
			eface = *(*any)(v.ptr)
		} else {
			eface = (any)(*(*interface {
				M()
			})(v.ptr))
		}
		x := unpackEface(eface)
		if x.flag != 0 {
			x.flag |= v.flag.ro()
		}
		return x
	case Pointer:
		ptr := v.ptr
		if v.flag&flagIndir != 0 {
			if ifaceIndir(v.typ) {
				// 这是指向非堆内对象的指针。ptr指向堆中的uintptr 
				// 。uintptr是非堆内对象的地址。
				// 一般来说，指向堆内对象之外的指针可能完全是垃圾。
				// 但Elem（）要求取消引用它，因此用户断言
				// 至少它是一个有效指针（而不仅仅是存储在
				// 指针槽中的整数）。让我们检查一下，以确保它不是一个指针
				// 如果在GC或写障碍期间看到它，运行时将崩溃。
				// 因为它不是堆内指针，所以所有指向堆的指针都是
				// 禁止的！这使得测试非常容易。
				// 见第48399期。
				if !verifyNotInHeapPtr(*(*uintptr)(ptr)) {
					panic("reflect: reflect.Value.Elem on an invalid notinheap pointer")
				}
			}
			ptr = *(*unsafe.Pointer)(ptr)
		}
		// 返回值的地址是v的值。
		if ptr == nil {
			return Value{}
		}
		tt := (*ptrType)(unsafe.Pointer(v.typ))
		typ := tt.elem
		fl := v.flag&flagRO | flagIndir | flagAddr
		fl |= flag(typ.Kind())
		return Value{typ, ptr, fl}
	}
	panic(&ValueError{"reflect.Value.Elem", v.kind()})
}

// 字段返回结构v的第i个字段。
// 如果v的种类不是结构或i超出范围，它将崩溃。
func (v Value) Field(i int) Value {
	if v.kind() != Struct {
		panic(&ValueError{"reflect.Value.Field", v.kind()})
	}
	tt := (*structType)(unsafe.Pointer(v.typ))
	if uint(i) >= uint(len(tt.fields)) {
		panic("reflect: Field index out of range")
	}
	field := &tt.fields[i]
	typ := field.typ

	// 从v继承权限位，但清除Flagmbedro。
	fl := v.flag&(flagStickyRO|flagIndir|flagAddr) | flag(typ.Kind())
	// 使用未报告的野战部队flagRO。
	if !field.name.isExported() {
		if field.embedded() {
			fl |= flagEmbedRO
		} else {
			fl |= flagStickyRO
		}
	}
	// 要么设置了flagIndir，v.ptr指向struct，要么未设置flagIndir，v.ptr是实际的struct数据。
	// 在前一种情况下，我们需要v.ptr+offset。
	// 在后一种情况下，我们必须有字段。偏移量=0，
	// so v.ptr+字段。偏移量仍然是正确的地址。
	ptr := add(v.ptr, field.offset(), "same as non-reflect &v.field")
	return Value{typ, ptr, fl}
}

// FieldByIndex返回索引对应的嵌套字段。
// 如果求值需要单步执行nil 
// 指针或非结构的字段，则会出现恐慌。
func (v Value) FieldByIndex(index []int) Value {
	if len(index) == 1 {
		return v.Field(index[0])
	}
	v.mustBe(Struct)
	for i, x := range index {
		if i > 0 {
			if v.Kind() == Pointer && v.typ.Elem().Kind() == Struct {
				if v.IsNil() {
					panic("reflect: indirection through nil pointer to embedded struct")
				}
				v = v.Elem()
			}
		}
		v = v.Field(x)
	}
	return v
}

// FieldByIndexer返回索引对应的嵌套字段。
// 如果计算需要单步执行nil 
// 指针，则返回错误；如果必须单步执行
// 不是结构的字段，则返回恐慌。
func (v Value) FieldByIndexErr(index []int) (Value, error) {
	if len(index) == 1 {
		return v.Field(index[0]), nil
	}
	v.mustBe(Struct)
	for i, x := range index {
		if i > 0 {
			if v.Kind() == Ptr && v.typ.Elem().Kind() == Struct {
				if v.IsNil() {
					return Value{}, errors.New("reflect: indirection through nil pointer to embedded struct field " + v.typ.Elem().Name())
				}
				v = v.Elem()
			}
		}
		v = v.Field(x)
	}
	return v, nil
}

// FieldByName返回具有给定名称的结构字段。
// 如果找不到字段，则返回零值。
// 如果v的种类不是struct，它会恐慌。
func (v Value) FieldByName(name string) Value {
	v.mustBe(Struct)
	if f, ok := v.typ.FieldByName(name); ok {
		return v.FieldByIndex(f.Index)
	}
	return Value{}
}

// FieldByNameFunc返回满足匹配函数的名为
// 的结构字段。
// 如果v的种类不是struct，它会恐慌。
// 如果找不到字段，则返回零值。
func (v Value) FieldByNameFunc(match func(string) bool) Value {
	if f, ok := v.typ.FieldByNameFunc(match); ok {
		return v.FieldByIndex(f.Index)
	}
	return Value{}
}

// CanFloat报告Float是否可以在不惊慌的情况下使用。
func (v Value) CanFloat() bool {
	switch v.kind() {
	case Float32, Float64:
		return true
	default:
		return false
	}
}

// Float返回v的基础值，作为float64。
// 如果v的种类不是Float32或Float64，它会惊慌失措
func (v Value) Float() float64 {
	k := v.kind()
	switch k {
	case Float32:
		return float64(*(*float32)(v.ptr))
	case Float64:
		return *(*float64)(v.ptr)
	}
	panic(&ValueError{"reflect.Value.Float", v.kind()})
}

var uint8Type = TypeOf(uint8(0)).(*rtype)

// 索引返回v的第i个元素。
// 如果v的种类不是数组、切片或字符串，或者i超出范围，它就会恐慌。
func (v Value) Index(i int) Value {
	switch v.kind() {
	case Array:
		tt := (*arrayType)(unsafe.Pointer(v.typ))
		if uint(i) >= uint(tt.len) {
			panic("reflect: array index out of range")
		}
		typ := tt.elem
		offset := uintptr(i) * typ.size

		// 设置了flagIndir且v.ptr指向阵列，
		// 或未设置flagIndir且v.ptr为实际阵列数据。
		// 在前一种情况下，我们需要v.ptr+offset。在后一种情况下，我们必须做索引（0），所以offset=0，所以v.ptr+offset仍然是正确的地址。
		val := add(v.ptr, offset, "same as &v[i], i < tt.len")
		fl := v.flag&(flagIndir|flagAddr) | v.flag.ro() | flag(typ.Kind()) // 位与整个数组相同
		return Value{typ, val, fl}

	case Slice:
		// 元素标志与指针的元素相同。
		// 可寻址，间接，可能只读。
		s := (*unsafeheader.Slice)(v.ptr)
		if uint(i) >= uint(s.Len) {
			panic("reflect: slice index out of range")
		}
		tt := (*sliceType)(unsafe.Pointer(v.typ))
		typ := tt.elem
		val := arrayAt(s.Data, i, typ.size, "i < s.Len")
		fl := flagAddr | flagIndir | v.flag.ro() | flag(typ.Kind())
		return Value{typ, val, fl}

	case String:
		s := (*unsafeheader.String)(v.ptr)
		if uint(i) >= uint(s.Len) {
			panic("reflect: string index out of range")
		}
		p := arrayAt(s.Data, i, 1, "i < s.Len")
		fl := v.flag.ro() | flag(Uint8) | flagIndir
		return Value{uint8Type, p, fl}
	}
	panic(&ValueError{"reflect.Value.Index", v.kind()})
}

// CanInt报告Int是否可以在不惊慌的情况下使用。
func (v Value) CanInt() bool {
	switch v.kind() {
	case Int, Int8, Int16, Int32, Int64:
		return true
	default:
		return false
	}
}

// Int返回v的基础值，作为int64。
// 如果v的种类不是Int、Int8、Int16、Int32或Int64，它就会恐慌。
func (v Value) Int() int64 {
	k := v.kind()
	p := v.ptr
	switch k {
	case Int:
		return int64(*(*int)(p))
	case Int8:
		return int64(*(*int8)(p))
	case Int16:
		return int64(*(*int16)(p))
	case Int32:
		return int64(*(*int32)(p))
	case Int64:
		return *(*int64)(p)
	}
	panic(&ValueError{"reflect.Value.Int", v.kind()})
}

// CanInterface报告界面是否可以在不惊慌的情况下使用。
func (v Value) CanInterface() bool {
	if v.flag == 0 {
		panic(&ValueError{"reflect.Value.CanInterface", Invalid})
	}
	return v.flag&flagRO == 0
}

// 接口将v的当前值作为接口{}返回。
// 它相当于：
// var i接口{}=（v的基础值）
// 如果通过访问
// 未报告的结构字段来获取该值，则会出现恐慌。
func (v Value) Interface() (i any) {
	return valueInterface(v, true)
}

func valueInterface(v Value, safe bool) any {
	if v.flag == 0 {
		panic(&ValueError{"reflect.Value.Interface", Invalid})
	}
	if safe && v.flag&flagRO != 0 {
		// 不允许通过接口访问未报告的值，
		// 因为它们可能是不应为
		// 可写的指针或不应调用的方法或函数。
		panic("reflect.Value.Interface: cannot return value obtained from unexported field or method")
	}
	if v.flag&flagMethod != 0 {
		v = makeMethodValue("Interface", v)
	}

	if v.kind() == Interface {
		// 特殊情况：返回接口内的元素。
		// 空接口有一个布局，所有带有
		// 方法的接口都有第二个布局。
		if v.NumMethod() == 0 {
			return *(*any)(v.ptr)
		}
		return *(*interface {
			M()
		})(v.ptr)
	}

	// TODO:将safe传递给packEface，以便在safe==true时不需要复制？
	return packEface(v)
}

// InterfaceData返回一对未指定的uintptr值。
// 如果v的种类不是接口，它会感到恐慌。
// 
// 在Go的早期版本中，此函数返回接口的
// 作为uintptr对的值。从Go 1.4开始，
// 接口值的实现禁止任何定义的InterfaceData使用。
// 
// 已弃用：接口值的内存表示形式与InterfaceData不兼容。
func (v Value) InterfaceData() [2]uintptr {
	v.mustBe(Interface)
	// 我们将其视为一个读取操作，因此我们允许
	// 即使对于未报告的数据也可以使用它，因为调用方
	// 必须导入“不安全”才能将其转换为可被滥用的内容。
	// 接口值总是大于一个单词；假设是flagIndir。
	return *(*[2]uintptr)(v.ptr)
}

// IsNil报告其参数v是否为零。参数必须是
// 一个chan、func、interface、map、pointer或slice值；如果是
// 不是，则无恐慌。请注意，IsNil并不总是等同于
// 与Go中的nil进行常规比较。例如，如果通过使用未初始化的接口变量i调用ValueOf来创建v，则
// i==nil将为真，但v.IsNil将死机，因为v将是零
// 值。
func (v Value) IsNil() bool {
	k := v.kind()
	switch k {
	case Chan, Func, Map, Pointer, UnsafePointer:
		if v.flag&flagMethod != 0 {
			return false
		}
		ptr := v.ptr
		if v.flag&flagIndir != 0 {
			ptr = *(*unsafe.Pointer)(ptr)
		}
		return ptr == nil
	case Interface, Slice:
		// 如果第一个字为0，则接口和切片都为零。
		// 两者都比一个词大；假设是flagIndir。
		return *(*unsafe.Pointer)(v.ptr) == nil
	}
	panic(&ValueError{"reflect.Value.IsNil", v.kind()})
}

// 报告v是否代表值是有效的。
// 如果v是零值，则返回false。
// 如果IsValid返回false，则返回除String panic之外的所有其他方法。
// 大多数函数和方法从不返回无效值。
// 如果有，其文档会明确说明条件。
func (v Value) IsValid() bool {
	return v.flag != 0
}

// IsZero报告v是否为其类型的零值。
// 如果参数无效，它会惊慌失措。
func (v Value) IsZero() bool {
	switch v.kind() {
	case Bool:
		return !v.Bool()
	case Int, Int8, Int16, Int32, Int64:
		return v.Int() == 0
	case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
		return v.Uint() == 0
	case Float32, Float64:
		return math.Float64bits(v.Float()) == 0
	case Complex64, Complex128:
		c := v.Complex()
		return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0
	case Array:
		for i := 0; i < v.Len(); i++ {
			if !v.Index(i).IsZero() {
				return false
			}
		}
		return true
	case Chan, Func, Interface, Map, Pointer, Slice, UnsafePointer:
		return v.IsNil()
	case String:
		return v.Len() == 0
	case Struct:
		for i := 0; i < v.NumField(); i++ {
			if !v.Field(i).IsZero() {
				return false
			}
		}
		return true
	default:
		// 这种情况永远不会发生，但会在以后作为
		// 的保护措施，因为默认值在这里没有意义。
		panic(&ValueError{"reflect.Value.IsZero", v.Kind()})
	}
}

// Kind返回v的种类。
// 如果v是零值（IsValid返回false），Kind返回无效。
func (v Value) Kind() Kind {
	return v.kind()
}

// Len返回v的长度。
// 如果v的种类不是数组、Chan、Map、Slice或String，它就会恐慌。
func (v Value) Len() int {
	k := v.kind()
	switch k {
	case Array:
		tt := (*arrayType)(unsafe.Pointer(v.typ))
		return int(tt.len)
	case Chan:
		return chanlen(v.pointer())
	case Map:
		return maplen(v.pointer())
	case Slice:
		// 切片比一个单词大；假设是flagIndir。
		return (*unsafeheader.Slice)(v.ptr).Len
	case String:
		// 字符串大于一个单词；假设是flagIndir。
		return (*unsafeheader.String)(v.ptr).Len
	}
	panic(&ValueError{"reflect.Value.Len", v.kind()})
}

// MapIndex返回与映射v中的键相关的值。
// 如果v的种类不是映射，则会导致恐慌。
// 如果在映射中找不到键，或者如果v表示nil映射，则返回零值。
// 在Go中，键的值必须可分配给映射的键类型。
func (v Value) MapIndex(key Value) Value {
	v.mustBe(Map)
	tt := (*mapType)(unsafe.Pointer(v.typ))

	// 不需要导出密钥，这样DeepEqual 
	// 和其他程序可以使用
	// 返回的所有密钥作为MapIndex的参数。但是，如果映射
	// 或密钥未报告，则结果将被视为未报告。这与结构的
	// 行为一致，该行为允许读取但不允许写入未报告的字段。

	var e unsafe.Pointer
	if key.kind() == String && tt.key.Kind() == String && tt.elem.size <= maxValSize {
		k := *(*string)(key.ptr)
		e = mapaccess_faststr(v.typ, v.pointer(), k)
	} else {
		key = key.assignTo("reflect.Value.MapIndex", tt.key, nil)
		var k unsafe.Pointer
		if key.flag&flagIndir != 0 {
			k = key.ptr
		} else {
			k = unsafe.Pointer(&key.ptr)
		}
		e = mapaccess(v.typ, v.pointer(), k)
	}
	if e == nil {
		return Value{}
	}
	typ := tt.elem
	fl := (v.flag | key.flag).ro()
	fl |= flag(typ.Kind())
	return copyVal(typ, fl, e)
}

// MapKeys返回一个包含地图中所有键的切片，
// 顺序未指定。
// 如果v的种类不是地图，它会恐慌。
// 如果v代表nil映射，则返回一个空切片。
func (v Value) MapKeys() []Value {
	v.mustBe(Map)
	tt := (*mapType)(unsafe.Pointer(v.typ))
	keyType := tt.key

	fl := v.flag.ro() | flag(keyType.Kind())

	m := v.pointer()
	mlen := int(0)
	if m != nil {
		mlen = maplen(m)
	}
	var it hiter
	mapiterinit(v.typ, m, &it)
	a := make([]Value, mlen)
	var i int
	for i = 0; i < len(a); i++ {
		key := mapiterkey(&it)
		if key == nil {
			// 有人从地图上删除了一个条目，因为我们
			// 在上面给maplen打了电话。这是一场数据竞赛，但我们无能为力。
			break
		}
		a[i] = copyVal(keyType, fl, key)
		mapiternext(&it)
	}
	return a[:i]
}

// hiter的结构与运行时匹配。希特的结构。
// 这里有一个克隆，允许我们在类型MapIter中嵌入一个映射迭代器
// 这样就可以在不进行任何分配的情况下重用MapIter 
// 了。
type hiter struct {
	key         unsafe.Pointer
	elem        unsafe.Pointer
	t           unsafe.Pointer
	h           unsafe.Pointer
	buckets     unsafe.Pointer
	bptr        unsafe.Pointer
	overflow    *[]unsafe.Pointer
	oldoverflow *[]unsafe.Pointer
	startBucket uintptr
	offset      uint8
	wrapped     bool
	B           uint8
	i           uint8
	bucket      uintptr
	checkBucket uintptr
}

func (h *hiter) initialized() bool {
	return h.t != nil
}

// 映射器是在地图上进行测距的迭代器。
// 请参阅值。地图范围。
type MapIter struct {
	m     Value
	hiter hiter
}

// Key返回iter当前映射条目的密钥。
func (iter *MapIter) Key() Value {
	if !iter.hiter.initialized() {
		panic("MapIter.Key called before Next")
	}
	iterkey := mapiterkey(&iter.hiter)
	if iterkey == nil {
		panic("MapIter.Key called on exhausted iterator")
	}

	t := (*mapType)(unsafe.Pointer(iter.m.typ))
	ktype := t.key
	return copyVal(ktype, iter.m.flag.ro()|flag(ktype.Kind()), iterkey)
}

// SetIterKey将iter当前map条目的密钥分配给v。
// 它相当于v.Set（iter.Key（）），但它避免分配新值。
// 在Go中，密钥必须可分配给v的类型。
func (v Value) SetIterKey(iter *MapIter) {
	if !iter.hiter.initialized() {
		panic("reflect: Value.SetIterKey called before Next")
	}
	iterkey := mapiterkey(&iter.hiter)
	if iterkey == nil {
		panic("reflect: Value.SetIterKey called on exhausted iterator")
	}

	v.mustBeAssignable()
	var target unsafe.Pointer
	if v.kind() == Interface {
		target = v.ptr
	}

	t := (*mapType)(unsafe.Pointer(iter.m.typ))
	ktype := t.key

	key := Value{ktype, iterkey, iter.m.flag | flag(ktype.Kind()) | flagIndir}
	key = key.assignTo("reflect.MapIter.SetKey", v.typ, target)
	typedmemmove(v.typ, v.ptr, key.ptr)
}

// Value返回iter当前映射项的值。
func (iter *MapIter) Value() Value {
	if !iter.hiter.initialized() {
		panic("MapIter.Value called before Next")
	}
	iterelem := mapiterelem(&iter.hiter)
	if iterelem == nil {
		panic("MapIter.Value called on exhausted iterator")
	}

	t := (*mapType)(unsafe.Pointer(iter.m.typ))
	vtype := t.elem
	return copyVal(vtype, iter.m.flag.ro()|flag(vtype.Kind()), iterelem)
}

// SetIterValue将iter当前映射条目的值赋值给v。
// 它相当于v.Set（iter.Value（）），但它避免分配新值。
// 在Go中，该值必须可分配给v的类型。
func (v Value) SetIterValue(iter *MapIter) {
	if !iter.hiter.initialized() {
		panic("reflect: Value.SetIterValue called before Next")
	}
	iterelem := mapiterelem(&iter.hiter)
	if iterelem == nil {
		panic("reflect: Value.SetIterValue called on exhausted iterator")
	}

	v.mustBeAssignable()
	var target unsafe.Pointer
	if v.kind() == Interface {
		target = v.ptr
	}

	t := (*mapType)(unsafe.Pointer(iter.m.typ))
	vtype := t.elem

	elem := Value{vtype, iterelem, iter.m.flag | flag(vtype.Kind()) | flagIndir}
	elem = elem.assignTo("reflect.MapIter.SetValue", v.typ, target)
	typedmemmove(v.typ, v.ptr, elem.ptr)
}

// 下一步将推进映射迭代器，并报告是否还有另一个
// 条目。iter耗尽时返回false；后续的
// 对Key、Value或Next的调用将导致恐慌。
func (iter *MapIter) Next() bool {
	if !iter.m.IsValid() {
		panic("MapIter.Next called on an iterator that does not have an associated map Value")
	}
	if !iter.hiter.initialized() {
		mapiterinit(iter.m.typ, iter.m.pointer(), &iter.hiter)
	} else {
		if mapiterkey(&iter.hiter) == nil {
			panic("MapIter.Next called on exhausted iterator")
		}
		mapiternext(&iter.hiter)
	}
	return mapiterkey(&iter.hiter) != nil
}

// 重置修改国际热核实验堆以在v.
// 如果v的种类不是映射，v不是零值，它就会恐慌。
// 重置（值{}）使iter不引用任何映射，
// 这可能会允许对之前迭代的映射进行垃圾收集。
func (iter *MapIter) Reset(v Value) {
	if v.IsValid() {
		v.mustBe(Map)
	}
	iter.m = v
	iter.hiter = hiter{}
}

// MapRange返回映射的范围迭代器。
// 如果v的种类不是地图，它会恐慌。
// 
// 调用Next以推进迭代器，并使用Key/Value访问每个条目。
// Next在迭代器耗尽时返回false。
// MapRange遵循与range语句相同的迭代语义。
// 
// 示例：
// 
// iter:=reflect。价值（m）。国际热核实验堆的MapRange（）
// 。Next（）{
// k:=iter.Key（）
// v:=iter.Value（）
// …
// }
// 
func (v Value) MapRange() *MapIter {
	v.mustBe(Map)
	return &MapIter{m: v}
}

// copyVal返回一个包含映射键或ptr处的值，
// /根据需要分配一个新变量。
func copyVal(typ *rtype, fl flag, ptr unsafe.Pointer) Value {
	if ifaceIndir(typ) {
		// 复制结果，以便将来对地图的更改
		// 不会更改基础值。
		c := unsafe_New(typ)
		typedmemmove(typ, c, ptr)
		return Value{typ, c, fl | flagIndir}
	}
	return Value{typ, *(*unsafe.Pointer)(ptr), fl}
}

// 方法返回与v的第i个方法对应的函数值。
// 调用返回函数的参数不应包括
// 接收方；返回的函数将始终使用v作为接收器。
// 如果i超出范围或v是nil接口值，则方法会崩溃。
func (v Value) Method(i int) Value {
	if v.typ == nil {
		panic(&ValueError{"reflect.Value.Method", Invalid})
	}
	if v.flag&flagMethod != 0 || uint(i) >= uint(v.typ.NumMethod()) {
		panic("reflect: Method index out of range")
	}
	if v.typ.Kind() == Interface && v.IsNil() {
		panic("reflect: Method on nil interface value")
	}
	fl := v.flag.ro() | (v.flag & flagIndir)
	fl |= flag(Func)
	fl |= flag(i)<<flagMethodShift | flagMethod
	return Value{v.typ, v.ptr, fl}
}

// NumMethod返回值的方法集中导出的方法数。
func (v Value) NumMethod() int {
	if v.typ == nil {
		panic(&ValueError{"reflect.Value.NumMethod", Invalid})
	}
	if v.flag&flagMethod != 0 {
		return 0
	}
	return v.typ.NumMethod()
}

// MethodByName返回一个函数值，该值对应于具有给定名称的v的方法
// 。
// 对返回函数的调用的参数不应包括
// 接收方；返回的函数将始终使用v作为接收器。
// 如果找不到方法，则返回零值。
func (v Value) MethodByName(name string) Value {
	if v.typ == nil {
		panic(&ValueError{"reflect.Value.MethodByName", Invalid})
	}
	if v.flag&flagMethod != 0 {
		return Value{}
	}
	m, ok := v.typ.MethodByName(name)
	if !ok {
		return Value{}
	}
	return v.Method(m.Index)
}

// NumField返回结构v中的字段数。
// 如果v的种类不是结构，则会出现恐慌。
func (v Value) NumField() int {
	v.mustBe(Struct)
	tt := (*structType)(unsafe.Pointer(v.typ))
	return len(tt.fields)
}

// OverflowComplex报告complex128 x是否不能用v的类型表示。
// 如果v的类型不是Complex64或Complex128，它就会恐慌。
func (v Value) OverflowComplex(x complex128) bool {
	k := v.kind()
	switch k {
	case Complex64:
		return overflowFloat32(real(x)) || overflowFloat32(imag(x))
	case Complex128:
		return false
	}
	panic(&ValueError{"reflect.Value.OverflowComplex", v.kind()})
}

// OverflowFloat报告float64 x是否不能用v的类型表示。
// 如果v的种类不是Float32或Float64，它会恐慌。
func (v Value) OverflowFloat(x float64) bool {
	k := v.kind()
	switch k {
	case Float32:
		return overflowFloat32(x)
	case Float64:
		return false
	}
	panic(&ValueError{"reflect.Value.OverflowFloat", v.kind()})
}

func overflowFloat32(x float64) bool {
	if x < 0 {
		x = -x
	}
	return math.MaxFloat32 < x && x <= math.MaxFloat64
}

// OverflowInt报告int64 x是否不能用v的类型表示。
// 如果v的种类不是Int、Int8、Int16、Int32或Int64，它就会恐慌。
func (v Value) OverflowInt(x int64) bool {
	k := v.kind()
	switch k {
	case Int, Int8, Int16, Int32, Int64:
		bitSize := v.typ.size * 8
		trunc := (x << (64 - bitSize)) >> (64 - bitSize)
		return x != trunc
	}
	panic(&ValueError{"reflect.Value.OverflowInt", v.kind()})
}

// OverflowUint报告uint64 x是否不能用v的类型表示。
// 如果v的种类不是Uint、uintpttr、Uint8、Uint16、Uint32或Uint64，它就会恐慌。
func (v Value) OverflowUint(x uint64) bool {
	k := v.kind()
	switch k {
	case Uint, Uintptr, Uint8, Uint16, Uint32, Uint64:
		bitSize := v.typ.size * 8
		trunc := (x << (64 - bitSize)) >> (64 - bitSize)
		return x != trunc
	}
	panic(&ValueError{"reflect.Value.OverflowUint", v.kind()})
}

// go:nocheckptr 
// 这会阻止内联值。启用-d=checkptr时的指针，
// 这确保cmd/compile可以识别不安全。指针（v.Pointer（））
// 并做一个例外。

// 指针将v的值作为uintptr返回。
// 返回uintptr而不是不安全。指针，使
// 使用反射的代码无法获取不安全的信息。指针
// 不显式导入不安全的包。
// 如果v的种类不是Chan、Func、Map、Pointer、Slice或UnsafePointer，它就会恐慌。
// 
// 如果v的种类是Func，则返回的指针是基础
// 代码指针，但不一定足以唯一标识单个函数。唯一的保证是当且仅当v是nil func值时，
// 结果为零。
// 
// 如果v的种类是Slice，则返回的指针指向Slice的第一个
// 元素。如果切片为nil，则返回值
// 为0。如果切片为空但非nil，则返回值为非零。
// 
// 最好使用uintptr（Value.UnsafePointer（））来获得等效的结果。
func (v Value) Pointer() uintptr {
	k := v.kind()
	switch k {
	case Pointer:
		if v.typ.ptrdata == 0 {
			val := *(*uintptr)(v.ptr)
			// 因为它不是堆内指针，所以所有指向堆的指针都是
			// 禁止！请参见价值评论。元素与问题#48399。
			if !verifyNotInHeapPtr(val) {
				panic("reflect: reflect.Value.Pointer on an invalid notinheap pointer")
			}
			return val
		}
		fallthrough
	case Chan, Map, UnsafePointer:
		return uintptr(v.pointer())
	case Func:
		if v.flag&flagMethod != 0 {
			// 正如doc注释所说，返回的指针是一个
			// 底层代码指针，但不一定足以唯一标识单个函数。通过reflect创建的所有方法表达式
			// 都有相同的底层代码指针
			// 因此它们的指针相等。此处使用的函数必须与makeMethodValue中使用的函数匹配。
			return methodValueCallCodePtr()
		}
		p := v.pointer()
		// 非零func值指向数据块。
		// 数据块的第一个字是实际代码。
		if p != nil {
			p = *(*unsafe.Pointer)(p)
		}
		return uintptr(p)

	case Slice:
		return (*SliceHeader)(v.ptr).Data
	}
	panic(&ValueError{"reflect.Value.Pointer", v.kind()})
}

// Recv从v频道接收并返回一个值。
// 如果v的种类不是Chan，它会惊慌失措。
// 接收阻塞，直到值准备就绪。
// 如果值x对应于通道上的发送
// 则布尔值ok为真，如果由于通道关闭而接收到零值则为假。
func (v Value) Recv() (x Value, ok bool) {
	v.mustBe(Chan)
	v.mustBeExported()
	return v.recv(false)
}

// 内部recv，可能为非阻塞（nb）。
// v是已知的频道。
func (v Value) recv(nb bool) (val Value, ok bool) {
	tt := (*chanType)(unsafe.Pointer(v.typ))
	if ChanDir(tt.dir)&RecvDir == 0 {
		panic("reflect: recv on send-only channel")
	}
	t := tt.elem
	val = Value{t, nil, flag(t.Kind())}
	var p unsafe.Pointer
	if ifaceIndir(t) {
		p = unsafe_New(t)
		val.ptr = p
		val.flag |= flagIndir
	} else {
		p = unsafe.Pointer(&val.ptr)
	}
	selected, ok := chanrecv(v.pointer(), nb, p)
	if !selected {
		val = Value{}
	}
	return
}

// Send在频道v上发送x。
// 如果v的种类不是Chan，或者x的类型与v的元素类型不相同，它就会恐慌。
// 在Go中，x的值必须可分配给通道的元素类型。
func (v Value) Send(x Value) {
	v.mustBe(Chan)
	v.mustBeExported()
	v.send(x, false)
}

// 内部发送，可能是非阻塞的。
// v被认为是一个频道。
func (v Value) send(x Value, nb bool) (selected bool) {
	tt := (*chanType)(unsafe.Pointer(v.typ))
	if ChanDir(tt.dir)&SendDir == 0 {
		panic("reflect: send on recv-only channel")
	}
	x.mustBeExported()
	x = x.assignTo("reflect.Value.Send", tt.elem, nil)
	var p unsafe.Pointer
	if x.flag&flagIndir != 0 {
		p = x.ptr
	} else {
		p = unsafe.Pointer(&x.ptr)
	}
	return chansend(v.pointer(), p, nb)
}

// Set将x赋值给值v。
// 如果CanSet返回false，它将崩溃。
// 在Go中，x的值必须可分配给v的类型。
func (v Value) Set(x Value) {
	v.mustBeAssignable()
	x.mustBeExported() // 不要让未报告的x泄漏
	var target unsafe.Pointer
	if v.kind() == Interface {
		target = v.ptr
	}
	x = x.assignTo("reflect.Set", v.typ, target)
	if x.flag&flagIndir != 0 {
		if x.ptr == unsafe.Pointer(&zeroVal[0]) {
			typedmemclr(v.typ, v.ptr)
		} else {
			typedmemmove(v.typ, v.ptr, x.ptr)
		}
	} else {
		*(*unsafe.Pointer)(v.ptr) = x.ptr
	}
}

// SetBool设置v的基础值。
// 如果v的种类不是Bool，或者CanSet（）是false，它就会恐慌。
func (v Value) SetBool(x bool) {
	v.mustBeAssignable()
	v.mustBe(Bool)
	*(*bool)(v.ptr) = x
}

// SetBytes设置v的基本值。
// 如果v的底层值不是字节片，它就会恐慌。
func (v Value) SetBytes(x []byte) {
	v.mustBeAssignable()
	v.mustBe(Slice)
	if v.typ.Elem().Kind() != Uint8 {
		panic("reflect.Value.SetBytes of non-byte slice")
	}
	*(*[]byte)(v.ptr) = x
}

// setRunes设置v的基础值。
// 如果v的基本值不是一段符文（int32s），它就会恐慌。
func (v Value) setRunes(x []rune) {
	v.mustBeAssignable()
	v.mustBe(Slice)
	if v.typ.Elem().Kind() != Int32 {
		panic("reflect.Value.setRunes of non-rune slice")
	}
	*(*[]rune)(v.ptr) = x
}

// SetComplex将v的基础值设置为x。如果v的种类不是Complex64或Complex128，或者如果CanSet（）为false，则会导致恐慌。
func (v Value) SetComplex(x complex128) {
	v.mustBeAssignable()
	switch k := v.kind(); k {
	default:
		panic(&ValueError{"reflect.Value.SetComplex", v.kind()})
	case Complex64:
		*(*complex64)(v.ptr) = complex64(x)
	case Complex128:
		*(*complex128)(v.ptr) = x
	}
}

// SetFloat将v的基础值设置为x。
// 如果v的种类不是Float32或Float64，或者如果CanSet（）为false，则会导致恐慌。
func (v Value) SetFloat(x float64) {
	v.mustBeAssignable()
	switch k := v.kind(); k {
	default:
		panic(&ValueError{"reflect.Value.SetFloat", v.kind()})
	case Float32:
		*(*float32)(v.ptr) = float32(x)
	case Float64:
		*(*float64)(v.ptr) = x
	}
}

// SetInt将v的基础值设置为x。
// 如果v的种类不是Int、Int8、Int16、Int32或Int64，或者如果CanSet（）为false，则会导致恐慌。
func (v Value) SetInt(x int64) {
	v.mustBeAssignable()
	switch k := v.kind(); k {
	default:
		panic(&ValueError{"reflect.Value.SetInt", v.kind()})
	case Int:
		*(*int)(v.ptr) = int(x)
	case Int8:
		*(*int8)(v.ptr) = int8(x)
	case Int16:
		*(*int16)(v.ptr) = int16(x)
	case Int32:
		*(*int32)(v.ptr) = int32(x)
	case Int64:
		*(*int64)(v.ptr) = x
	}
}

// SetLen将v的长度设置为n。
// 如果v的种类不是切片，或者如果n为负，或者
// 大于切片的容量，则会导致恐慌。
func (v Value) SetLen(n int) {
	v.mustBeAssignable()
	v.mustBe(Slice)
	s := (*unsafeheader.Slice)(v.ptr)
	if uint(n) > uint(s.Cap) {
		panic("reflect: slice length out of range in SetLen")
	}
	s.Len = n
}

// SetCap将v的容量设置为n。
// 如果v的种类不是切片，或者如果n小于长度，或者
// 大于切片的容量，则会导致恐慌。
func (v Value) SetCap(n int) {
	v.mustBeAssignable()
	v.mustBe(Slice)
	s := (*unsafeheader.Slice)(v.ptr)
	if n < s.Len || n > s.Cap {
		panic("reflect: slice capacity out of range in SetCap")
	}
	s.Cap = n
}

// SetMapIndex将与映射v中的键关联的元素设置为元素。
// 如果v的种类不是地图，它会恐慌。
// 如果elem是零值，则SetMapIndex会从映射中删除密钥。
// 否则，如果v持有一个nil映射，SetMapIndex将死机。
// 与Go一样，key的elem必须可分配给map的key type，
// 并且elem的值必须可分配给map的elem type。
func (v Value) SetMapIndex(key, elem Value) {
	v.mustBe(Map)
	v.mustBeExported()
	key.mustBeExported()
	tt := (*mapType)(unsafe.Pointer(v.typ))

	if key.kind() == String && tt.key.Kind() == String && tt.elem.size <= maxValSize {
		k := *(*string)(key.ptr)
		if elem.typ == nil {
			mapdelete_faststr(v.typ, v.pointer(), k)
			return
		}
		elem.mustBeExported()
		elem = elem.assignTo("reflect.Value.SetMapIndex", tt.elem, nil)
		var e unsafe.Pointer
		if elem.flag&flagIndir != 0 {
			e = elem.ptr
		} else {
			e = unsafe.Pointer(&elem.ptr)
		}
		mapassign_faststr(v.typ, v.pointer(), k, e)
		return
	}

	key = key.assignTo("reflect.Value.SetMapIndex", tt.key, nil)
	var k unsafe.Pointer
	if key.flag&flagIndir != 0 {
		k = key.ptr
	} else {
		k = unsafe.Pointer(&key.ptr)
	}
	if elem.typ == nil {
		mapdelete(v.typ, v.pointer(), k)
		return
	}
	elem.mustBeExported()
	elem = elem.assignTo("reflect.Value.SetMapIndex", tt.elem, nil)
	var e unsafe.Pointer
	if elem.flag&flagIndir != 0 {
		e = elem.ptr
	} else {
		e = unsafe.Pointer(&elem.ptr)
	}
	mapassign(v.typ, v.pointer(), k, e)
}

// SetUint将v的基本值设置为x。如果v的种类不是Uint、uintpttr、Uint8、Uint16、Uint32或Uint64，或者如果CanSet（）为false，则会导致恐慌。
func (v Value) SetUint(x uint64) {
	v.mustBeAssignable()
	switch k := v.kind(); k {
	default:
		panic(&ValueError{"reflect.Value.SetUint", v.kind()})
	case Uint:
		*(*uint)(v.ptr) = uint(x)
	case Uint8:
		*(*uint8)(v.ptr) = uint8(x)
	case Uint16:
		*(*uint16)(v.ptr) = uint16(x)
	case Uint32:
		*(*uint32)(v.ptr) = uint32(x)
	case Uint64:
		*(*uint64)(v.ptr) = x
	case Uintptr:
		*(*uintptr)(v.ptr) = uintptr(x)
	}
}

// SetPointer设置不安全的。指向x的指针值v.
// 如果v的种类不是非安全指针，它就会恐慌。
func (v Value) SetPointer(x unsafe.Pointer) {
	v.mustBeAssignable()
	v.mustBe(UnsafePointer)
	*(*unsafe.Pointer)(v.ptr) = x
}

// SetString将v的基础值设置为x。
// 如果v的种类不是字符串或CanSet（）为false，则会导致恐慌。
func (v Value) SetString(x string) {
	v.mustBeAssignable()
	v.mustBe(String)
	*(*string)(v.ptr) = x
}

// 切片返回v[i:j]。
// 如果v的种类不是数组、片或字符串，或者如果v是不可寻址数组，
// 或者如果索引超出范围，则会导致恐慌。
func (v Value) Slice(i, j int) Value {
	var (
		cap  int
		typ  *sliceType
		base unsafe.Pointer
	)
	switch kind := v.kind(); kind {
	default:
		panic(&ValueError{"reflect.Value.Slice", v.kind()})

	case Array:
		if v.flag&flagAddr == 0 {
			panic("reflect.Value.Slice: slice of unaddressable array")
		}
		tt := (*arrayType)(unsafe.Pointer(v.typ))
		cap = int(tt.len)
		typ = (*sliceType)(unsafe.Pointer(tt.slice))
		base = v.ptr

	case Slice:
		typ = (*sliceType)(unsafe.Pointer(v.typ))
		s := (*unsafeheader.Slice)(v.ptr)
		base = s.Data
		cap = s.Cap

	case String:
		s := (*unsafeheader.String)(v.ptr)
		if i < 0 || j < i || j > s.Len {
			panic("reflect.Value.Slice: string slice index out of bounds")
		}
		var t unsafeheader.String
		if i < s.Len {
			t = unsafeheader.String{Data: arrayAt(s.Data, i, 1, "i < s.Len"), Len: j - i}
		}
		return Value{v.typ, unsafe.Pointer(&t), v.flag}
	}

	if i < 0 || j < i || j > cap {
		panic("reflect.Value.Slice: slice index out of bounds")
	}

	// 声明切片，以便gc可以看到其中的基指针。
	var x []unsafe.Pointer

	// 重新解释为*unsafeheader。切片以进行编辑。
	s := (*unsafeheader.Slice)(unsafe.Pointer(&x))
	s.Len = j - i
	s.Cap = cap - i
	if cap-i > 0 {
		s.Data = arrayAt(base, i, typ.elem.Size(), "i < cap")
	} else {
		// 不要向前移动指针，以避免指向片的结尾之外
		s.Data = base
	}

	fl := v.flag.ro() | flagIndir | flag(Slice)
	return Value{typ.common(), unsafe.Pointer(&x), fl}
}

// 切片3是切片操作的三索引形式：它返回v[i:j:k]。
// 如果v的种类不是数组或切片，或者如果v是不可寻址数组，
// 或者如果索引超出范围，它就会恐慌。
func (v Value) Slice3(i, j, k int) Value {
	var (
		cap  int
		typ  *sliceType
		base unsafe.Pointer
	)
	switch kind := v.kind(); kind {
	default:
		panic(&ValueError{"reflect.Value.Slice3", v.kind()})

	case Array:
		if v.flag&flagAddr == 0 {
			panic("reflect.Value.Slice3: slice of unaddressable array")
		}
		tt := (*arrayType)(unsafe.Pointer(v.typ))
		cap = int(tt.len)
		typ = (*sliceType)(unsafe.Pointer(tt.slice))
		base = v.ptr

	case Slice:
		typ = (*sliceType)(unsafe.Pointer(v.typ))
		s := (*unsafeheader.Slice)(v.ptr)
		base = s.Data
		cap = s.Cap
	}

	if i < 0 || j < i || k < j || k > cap {
		panic("reflect.Value.Slice3: slice index out of bounds")
	}

	// 声明slice，以便垃圾收集器
	// 可以看到其中的基指针。
	var x []unsafe.Pointer

	// 重新解释为*unsafeheader。切片以进行编辑。
	s := (*unsafeheader.Slice)(unsafe.Pointer(&x))
	s.Len = j - i
	s.Cap = k - i
	if k-i > 0 {
		s.Data = arrayAt(base, i, typ.elem.Size(), "i < k <= cap")
	} else {
		// 不要向前移动指针，以避免指针指向片的结尾之外
		s.Data = base
	}

	fl := v.flag.ro() | flagIndir | flag(Slice)
	return Value{typ.common(), unsafe.Pointer(&x), fl}
}

// String以字符串形式返回字符串v的基础值。
// String是一个特例，因为Go的String方法约定。
// 与其他getter不同，如果v的种类不是字符串，它不会惊慌。
// 相反，它返回一个格式为“<T value>”的字符串，其中T是v的类型。
// fmt包专门处理值。它不会隐式调用它们的字符串
// 方法，而是打印它们所持有的具体值。
func (v Value) String() string {
	switch k := v.kind(); k {
	case Invalid:
		return "<invalid Value>"
	case String:
		return *(*string)(v.ptr)
	}
	// 如果你在反射上调用字符串。对于其他类型的值，最好打印一些内容，而不是惊慌失措。在调试中很有用。
	return "<" + v.Type().String() + " Value>"
}

// TryRecv尝试从通道v接收值，但不会阻塞。
// 如果v的类型不是Chan，它会感到恐慌。
// 如果receive传递了一个值，那么x是传递的值，ok是true。
// 如果接收无法在没有阻塞的情况下完成，则x为零值，ok为假。
// 如果通道关闭，x是通道元素类型的零值，ok为false。
func (v Value) TryRecv() (x Value, ok bool) {
	v.mustBe(Chan)
	v.mustBeExported()
	return v.recv(true)
}

// TrySend尝试在通道v上发送x，但不会阻止。
// 如果v的种类不是Chan，它会感到恐慌。
// 报告是否发送了值。
// 在Go中，x的值必须可分配给通道的元素类型。
func (v Value) TrySend(x Value) bool {
	v.mustBe(Chan)
	v.mustBeExported()
	return v.send(x, true)
}

// Type返回v的类型。
func (v Value) Type() Type {
	f := v.flag
	if f == 0 {
		panic(&ValueError{"reflect.Value.Type", Invalid})
	}
	if f&flagMethod == 0 {
		// 简单案例
		return v.typ
	}

	// 方法值。
	// v.typ描述的是接收者，而不是方法类型。
	i := int(v.flag) >> flagMethodShift
	if v.typ.Kind() == Interface {
		// 接口上的方法。
		tt := (*interfaceType)(unsafe.Pointer(v.typ))
		if uint(i) >= uint(len(tt.methods)) {
			panic("reflect: internal error: invalid method index")
		}
		m := &tt.methods[i]
		return v.typ.typeOff(m.typ)
	}
	// 混凝土类型的方法。
	ms := v.typ.exportedMethods()
	if uint(i) >= uint(len(ms)) {
		panic("reflect: internal error: invalid method index")
	}
	m := ms[i]
	return v.typ.typeOff(m.mtyp)
}

// CanUint报告Uint是否可以在不惊慌的情况下使用。
func (v Value) CanUint() bool {
	switch v.kind() {
	case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
		return true
	default:
		return false
	}
}

// Uint返回v的基础值，作为uint64。
// 如果v的种类不是Uint、uintpttr、Uint8、Uint16、Uint32或Uint64，它就会恐慌。
func (v Value) Uint() uint64 {
	k := v.kind()
	p := v.ptr
	switch k {
	case Uint:
		return uint64(*(*uint)(p))
	case Uint8:
		return uint64(*(*uint8)(p))
	case Uint16:
		return uint64(*(*uint16)(p))
	case Uint32:
		return uint64(*(*uint32)(p))
	case Uint64:
		return *(*uint64)(p)
	case Uintptr:
		return uint64(*(*uintptr)(p))
	}
	panic(&ValueError{"reflect.Value.Uint", v.kind()})
}

// go:nocheckptr 
// 这会阻止内联值。UnsafeAddr启用-d=checkptr时，
// 这确保cmd/compile可以识别不安全。指针（v.UnsafeAddr（））
// 并创建异常。

// UnsafeAddr返回指向v的数据的指针，作为uintptr。
// 适用于也导入“不安全”软件包的高级客户端。
// 如果v不可寻址，它会惊慌失措。
// 
// 最好使用uintptr（Value.Addr（）。UnsafePointer（））以获得等效结果。
func (v Value) UnsafeAddr() uintptr {
	if v.typ == nil {
		panic(&ValueError{"reflect.Value.UnsafeAddr", Invalid})
	}
	if v.flag&flagAddr == 0 {
		panic("reflect.Value.UnsafeAddr of unaddressable value")
	}
	return uintptr(v.ptr)
}

// UnsafePointer将v的值作为不安全值返回。指针。
// 如果v的种类不是Chan、Func、Map、Pointer、Slice或UnsafePointer，它就会恐慌。
// 
// 如果v的种类是Func，则返回的指针是一个底层
// 代码指针，但不一定足以唯一标识单个函数。唯一的保证是当且仅当v是nil func值时，
// 结果为零。
// 
// 如果v的种类是Slice，则返回的指针指向Slice的第一个
// 元素。如果切片为nil，则返回值
// 为nil。如果切片为空但非nil，则返回值为非nil。
func (v Value) UnsafePointer() unsafe.Pointer {
	k := v.kind()
	switch k {
	case Pointer:
		if v.typ.ptrdata == 0 {
			// 因为它不是堆内指针，所以所有指向堆的指针都是
			// 禁止的！请参见价值评论。元素与问题#48399。
			if !verifyNotInHeapPtr(*(*uintptr)(v.ptr)) {
				panic("reflect: reflect.Value.UnsafePointer on an invalid notinheap pointer")
			}
			return *(*unsafe.Pointer)(v.ptr)
		}
		fallthrough
	case Chan, Map, UnsafePointer:
		return v.pointer()
	case Func:
		if v.flag&flagMethod != 0 {
			// 正如doc注释所述，返回的指针是一个
			// 底层代码指针，但不一定足以唯一标识单个函数。通过reflect创建的所有方法表达式
			// 都有相同的底层代码指针
			// 因此它们的指针相等。此处使用的函数必须与makeMethodValue中使用的函数匹配。
			code := methodValueCallCodePtr()
			return *(*unsafe.Pointer)(unsafe.Pointer(&code))
		}
		p := v.pointer()
		// 非零func值指向数据块。
		// 数据块的第一个字是实际代码。
		if p != nil {
			p = *(*unsafe.Pointer)(p)
		}
		return p

	case Slice:
		return (*unsafeheader.Slice)(v.ptr).Data
	}
	panic(&ValueError{"reflect.Value.UnsafePointer", v.kind()})
}

// StringHeader是字符串的运行时表示形式。
// 不能安全或便携使用，其表示形式可能会在以后的版本中更改。此外，数据字段不足以保证数据不会被垃圾收集，因此程序必须保留一个单独的、正确键入的指向底层数据的指针。
type StringHeader struct {
	Data uintptr
	Len  int
}

// SliceHeader是切片的运行时表示形式。
// 不能安全或便携使用，其表示形式可能会在以后的版本中更改。
// 此外，数据字段不足以保证数据
// 它引用的数据不会被垃圾收集，因此程序必须保持
// 一个单独的、正确键入的指向底层数据的指针。
type SliceHeader struct {
	Data uintptr
	Len  int
	Cap  int
}

func typesMustMatch(what string, t1, t2 Type) {
	if t1 != t2 {
		panic(what + ": " + t1.String() + " != " + t2.String())
	}
}

// arrayAt返回p的第i个元素，
// 一个元素的大小为字节宽的数组。
// p指向的数组必须至少有i+1个元素：
// 传递i>=len是无效的（但无法在此处检查），因为这样结果将指向数组之外。
// whySafe必须解释为什么我<len。（通过“i<len”就可以了；
// 好处是在通话网站上展示这种假设。）
func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer {
	return add(p, uintptr(i)*eltSize, "i < len")
}

// 增加切片的大小，使其可以容纳更多的值，如果需要，分配
// 更多的容量。它还返回新旧切片长度。
func grow(s Value, extra int) (Value, int, int) {
	i0 := s.Len()
	i1 := i0 + extra
	if i1 < i0 {
		panic("reflect.Append: slice overflow")
	}
	m := s.Cap()
	if i1 <= m {
		return s.Slice(0, i1), i0, i1
	}
	if m == 0 {
		m = extra
	} else {
		const threshold = 256
		for m < i1 {
			if i0 < threshold {
				m += m
			} else {
				m += (m + 3*threshold) / 4
			}
		}
	}
	t := MakeSlice(s.Type(), i1, m)
	Copy(t, s)
	return t, i0, i1
}

// Append将值x追加到切片s并返回结果切片。
// 在Go中，每个x的值必须可分配给切片的元素类型。
func Append(s Value, x ...Value) Value {
	s.mustBe(Slice)
	s, i0, i1 := grow(s, len(x))
	for i, j := i0, 0; i < i1; i, j = i+1, j+1 {
		s.Index(i).Set(x[j])
	}
	return s
}

// AppendSlice将一个片t追加到片s，并返回结果片。
// 切片s和t必须具有相同的元素类型。
func AppendSlice(s, t Value) Value {
	s.mustBe(Slice)
	t.mustBe(Slice)
	typesMustMatch("reflect.AppendSlice", s.Type().Elem(), t.Type().Elem())
	s, i0, i1 := grow(s, t.Len())
	Copy(s.Slice(i0, i1), t)
	return s
}

// Copy将src的内容复制到dst中，直到
// dst已填充或src已耗尽。
// 返回复制的元素数。
// Dst和src都必须具有种类片或数组，并且
// Dst和src必须具有相同的元素类型。
// 
// 作为特例，如果dst的元素类型是kind Uint8，src可以有kind字符串。
func Copy(dst, src Value) int {
	dk := dst.kind()
	if dk != Array && dk != Slice {
		panic(&ValueError{"reflect.Copy", dk})
	}
	if dk == Array {
		dst.mustBeAssignable()
	}
	dst.mustBeExported()

	sk := src.kind()
	var stringCopy bool
	if sk != Array && sk != Slice {
		stringCopy = sk == String && dst.typ.Elem().Kind() == Uint8
		if !stringCopy {
			panic(&ValueError{"reflect.Copy", sk})
		}
	}
	src.mustBeExported()

	de := dst.typ.Elem()
	if !stringCopy {
		se := src.typ.Elem()
		typesMustMatch("reflect.Copy", de, se)
	}

	var ds, ss unsafeheader.Slice
	if dk == Array {
		ds.Data = dst.ptr
		ds.Len = dst.Len()
		ds.Cap = ds.Len
	} else {
		ds = *(*unsafeheader.Slice)(dst.ptr)
	}
	if sk == Array {
		ss.Data = src.ptr
		ss.Len = src.Len()
		ss.Cap = ss.Len
	} else if sk == Slice {
		ss = *(*unsafeheader.Slice)(src.ptr)
	} else {
		sh := *(*unsafeheader.String)(src.ptr)
		ss.Data = sh.Data
		ss.Len = sh.Len
		ss.Cap = sh.Len
	}

	return typedslicecopy(de.common(), ds, ss)
}

// runtimeSelect是传递给rselect的单个case。
// 这必须匹配/运行时/选择。go:/runtimeSelect 
type runtimeSelect struct {
	dir SelectDir      // 选择Send、SelectRecv或SelectDefault 
	typ *rtype         // 通道类型
	ch  unsafe.Pointer // 通道
	val unsafe.Pointer // ptr to data（SendDir）或ptr to receive buffer（RecvDir）
}

// rselect运行选择。它返回所选案例的索引。
// 如果案例是接收，则用接收值填写val。
// 常规OK bool指示接收是否与发送值对应。
// go:noescape 
func rselect([]runtimeSelect) (chosen int, recvOK bool)

// SelectDir描述所选案例的通信方向。
type SelectDir int

// 注意：这些值必须匹配/运行时/选择。开始：/selectDir。

const (
	_             SelectDir = iota
	SelectSend              // case Chan<-Send 
	SelectRecv              // case<-Chan:
	SelectDefault           // 默认
)

// SelectCase在select操作中描述单个案例。
// 案例的类型取决于Dir，即通信方向。
// 
// 如果Dir是SelectDefault，则大小写代表默认大小写。
// Chan和Send必须为零值。
// 
// 如果选择Dir发送，则大小写代表发送操作。
// 通常Chan的基础值必须是频道，Send的基础值必须是
// 可分配给频道的元素类型。作为一种特殊情况，如果Chan是一个零值，
// 则忽略该情况，并且Send字段也将被忽略，可能是零
// 或非零。
// 
// 如果选择了Dir，则大小写表示接收操作。
// 通常Chan的基础值必须是通道，Send必须是零值。
// 如果Chan是一个零值，那么案例将被忽略，但Send仍然必须是一个零值。
// 选择接收操作时，Select返回接收值。
// 
type SelectCase struct {
	Dir  SelectDir // 案例说明
	Chan Value     // 要使用的通道（用于发送或接收）
	Send Value     // 要发送的值
}

// Select执行案例列表中描述的选择操作。
// 与Go select语句一样，它会阻塞，直到至少一种情况
// 可以继续，进行统一的伪随机选择，然后执行该情况。它返回所选案例
// 的索引，如果该案例是接收操作，则返回接收到的值和
// 布尔值，指示该值是否对应于信道
// （与由于信道关闭而接收到的零值相反）。
// Select最多支持65536个案例。
func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) {
	if len(cases) > 65536 {
		panic("reflect.Select: too many cases (max 65536)")
	}
	// 注意：不要相信调用者没有修改下面的案例数据。
	// 该范围是安全的，因为调用者无法修改len的副本
	// 并且每次迭代都会生成自己的值c的副本。
	var runcases []runtimeSelect
	if len(cases) > 4 {
		// 由于依赖于运行时的容量，片被堆分配。
		runcases = make([]runtimeSelect, len(cases))
	} else {
		// 由于容量恒定，可以对片进行堆栈分配。
		runcases = make([]runtimeSelect, len(cases), 4)
	}

	haveDefault := false
	for i, c := range cases {
		rc := &runcases[i]
		rc.dir = c.Dir
		switch c.Dir {
		default:
			panic("reflect.Select: invalid Dir")

		case SelectDefault: // 默认
			if haveDefault {
				panic("reflect.Select: multiple default cases")
			}
			haveDefault = true
			if c.Chan.IsValid() {
				panic("reflect.Select: default case has Chan value")
			}
			if c.Send.IsValid() {
				panic("reflect.Select: default case has Send value")
			}

		case SelectSend:
			ch := c.Chan
			if !ch.IsValid() {
				break
			}
			ch.mustBe(Chan)
			ch.mustBeExported()
			tt := (*chanType)(unsafe.Pointer(ch.typ))
			if ChanDir(tt.dir)&SendDir == 0 {
				panic("reflect.Select: SendDir case using recv-only channel")
			}
			rc.ch = ch.pointer()
			rc.typ = &tt.rtype
			v := c.Send
			if !v.IsValid() {
				panic("reflect.Select: SendDir case missing Send value")
			}
			v.mustBeExported()
			v = v.assignTo("reflect.Select", tt.elem, nil)
			if v.flag&flagIndir != 0 {
				rc.val = v.ptr
			} else {
				rc.val = unsafe.Pointer(&v.ptr)
			}

		case SelectRecv:
			if c.Send.IsValid() {
				panic("reflect.Select: RecvDir case has Send value")
			}
			ch := c.Chan
			if !ch.IsValid() {
				break
			}
			ch.mustBe(Chan)
			ch.mustBeExported()
			tt := (*chanType)(unsafe.Pointer(ch.typ))
			if ChanDir(tt.dir)&RecvDir == 0 {
				panic("reflect.Select: RecvDir case using send-only channel")
			}
			rc.ch = ch.pointer()
			rc.typ = &tt.rtype
			rc.val = unsafe_New(tt.elem)
		}
	}

	chosen, recvOK = rselect(runcases)
	if runcases[chosen].dir == SelectRecv {
		tt := (*chanType)(unsafe.Pointer(runcases[chosen].typ))
		t := tt.elem
		p := runcases[chosen].val
		fl := flag(t.Kind())
		if ifaceIndir(t) {
			recv = Value{t, p, fl | flagIndir}
		} else {
			recv = Value{t, *(*unsafe.Pointer)(p), fl}
		}
	}
	return chosen, recv, recvOK
}

/*
 * constructors
 */

// 在包运行时中实现
func unsafe_New(*rtype) unsafe.Pointer
func unsafe_NewArray(*rtype, int) unsafe.Pointer

// MakeSicle为指定的切片类型、长度和容量创建一个新的零初始化切片值
// 。
func MakeSlice(typ Type, len, cap int) Value {
	if typ.Kind() != Slice {
		panic("reflect.MakeSlice of non-slice type")
	}
	if len < 0 {
		panic("reflect.MakeSlice: negative len")
	}
	if cap < 0 {
		panic("reflect.MakeSlice: negative cap")
	}
	if len > cap {
		panic("reflect.MakeSlice: len > cap")
	}

	s := unsafeheader.Slice{Data: unsafe_NewArray(typ.Elem().(*rtype), cap), Len: len, Cap: cap}
	return Value{typ.(*rtype), unsafe.Pointer(&s), flagIndir | flag(Slice)}
}

// MakeChan使用指定的类型和缓冲区大小创建一个新通道。
func MakeChan(typ Type, buffer int) Value {
	if typ.Kind() != Chan {
		panic("reflect.MakeChan of non-chan type")
	}
	if buffer < 0 {
		panic("reflect.MakeChan: negative buffer size")
	}
	if typ.ChanDir() != BothDir {
		panic("reflect.MakeChan: unidirectional channel type")
	}
	t := typ.(*rtype)
	ch := makechan(t, buffer)
	return Value{t, ch, flag(Chan)}
}

// MakeMap使用指定类型创建一个新映射。
func MakeMap(typ Type) Value {
	return MakeMapWithSize(typ, 0)
}

// MakeMapWithSize使用指定类型
// 和大约n个元素的初始空间创建一个新映射。
func MakeMapWithSize(typ Type, n int) Value {
	if typ.Kind() != Map {
		panic("reflect.MakeMapWithSize of non-map type")
	}
	t := typ.(*rtype)
	m := makemap(t, n)
	return Value{t, m, flag(Map)}
}

// 间接返回v指向的值。
// 如果v是零指针，则间接返回零值。
// 如果v不是指针，则间接返回v。
func Indirect(v Value) Value {
	if v.Kind() != Pointer {
		return v
	}
	return v.Elem()
}

// ValueOf返回初始化为接口i中存储的具体值
// 的新值。ValueOf（nil）返回零值。
func ValueOf(i any) Value {
	if i == nil {
		return Value{}
	}

	// TODO:可能允许值的内容存在于堆栈上。
	// 现在我们让内容总是逃到堆中。它使一些地方的生活变得更轻松（参见下面的chanrecv/mapassign 
	// 注释）。
	escapes(i)

	return unpackEface(i)
}

// Zero返回一个值，表示指定类型的零值。
// 结果与value结构的零值不同，
// 它完全不代表任何值。
// 例如，Zero（TypeOf（42））返回一个带有种类Int和值0的值。
// 返回的值既不可寻址也不可设置。
func Zero(typ Type) Value {
	if typ == nil {
		panic("reflect: Zero(nil)")
	}
	t := typ.(*rtype)
	fl := flag(t.Kind())
	if ifaceIndir(t) {
		var p unsafe.Pointer
		if t.size <= maxZero {
			p = unsafe.Pointer(&zeroVal[0])
		} else {
			p = unsafe_New(t)
		}
		return Value{t, p, fl | flagIndir}
	}
	return Value{t, nil, fl}
}

// 必须在运行时/映射中匹配声明。去
const maxZero = 1024

// go:linkname zeroVal运行时。zeroVal 
var zeroVal [maxZero]byte

// New返回一个值，该值表示指向指定类型的新零值
// 的指针。也就是说，返回值的类型是PointerTo（typ）。
func New(typ Type) Value {
	if typ == nil {
		panic("reflect: New(nil)")
	}
	t := typ.(*rtype)
	pt := t.ptrTo()
	if ifaceIndir(pt) {
		// 这是指向go:notinheap类型的指针。
		panic("reflect: New of type that may not be allocated in heap (possibly undefined cgo C type)")
	}
	ptr := unsafe_New(t)
	fl := flag(Pointer)
	return Value{pt, ptr, fl}
}

// NewAt返回一个值，该值表示指向指定类型的值的指针，使用p作为该指针。
func NewAt(typ Type, p unsafe.Pointer) Value {
	fl := flag(Pointer)
	t := typ.(*rtype)
	return Value{t.ptrTo(), p, fl}
}

// assignTo返回一个可以直接分配给typ的值v。
// 如果v不可分配给typ，它就会恐慌。
// 对于接口类型的转换，目标是建议使用的暂存空间。
// 目标必须为初始化内存（或零）。
func (v Value) assignTo(context string, dst *rtype, target unsafe.Pointer) Value {
	if v.flag&flagMethod != 0 {
		v = makeMethodValue(context, v)
	}

	switch {
	case directlyAssignable(dst, v.typ):
		// 覆盖类型以使它们匹配。
		// 相同的内存布局，因此不会造成任何伤害。
		fl := v.flag&(flagAddr|flagIndir) | v.flag.ro()
		fl |= flag(dst.Kind())
		return Value{dst, v.ptr, fl}

	case implements(dst, v.typ):
		if target == nil {
			target = unsafe_New(dst)
		}
		if v.Kind() == Interface && v.IsNil() {
			// 将nil ReadWriter传递给nil Reader是可以的，
			// 但是使用下面的ifaceE2I会引起恐慌。
			// 通过显式返回nil dst（例如读卡器）来避免恐慌。
			return Value{dst, nil, flag(Interface)}
		}
		x := valueInterface(v, false)
		if dst.NumMethod() == 0 {
			*(*any)(target) = x
		} else {
			ifaceE2I(dst, x, target)
		}
		return Value{dst, target, flagIndir | flag(Interface)}
	}

	// 失败。
	panic(context + ": value of type " + v.typ.String() + " is not assignable to type " + dst.String())
}

// Convert返回转换为t类型的值v。
// 如果通常的Go转换规则不允许将值v转换为t类型，或者如果将v转换为t类型，则转换为t类型。
func (v Value) Convert(t Type) Value {
	if v.flag&flagMethod != 0 {
		v = makeMethodValue("Convert", v)
	}
	op := convertOp(t.common(), v.typ)
	if op == nil {
		panic("reflect.Value.Convert: value of type " + v.typ.String() + " cannot be converted to type " + t.String())
	}
	return op(v, t)
}

// CanConvert报告值v是否可以转换为类型t。
// 如果v.CanConvert（t）返回true，那么v.Convert（t）将不会死机。
func (v Value) CanConvert(t Type) bool {
	vt := v.Type()
	if !vt.ConvertibleTo(t) {
		return false
	}
	// 目前唯一的转换类型
	// 是可以的，但根据值的不同，它可能会死机，这就是将
	// 从切片转换为指向数组的指针。
	if vt.Kind() == Slice && t.Kind() == Pointer && t.Elem().Kind() == Array {
		n := t.Elem().Len()
		if n > v.Len() {
			return false
		}
	}
	return true
}

// convertOp返回将src 
// 类型的值转换为dst类型的值的函数。如果转换是非法的，convertOp将返回nil。
func convertOp(dst, src *rtype) func(Value, Type) Value {
	switch src.Kind() {
	case Int, Int8, Int16, Int32, Int64:
		switch dst.Kind() {
		case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
			return cvtInt
		case Float32, Float64:
			return cvtIntFloat
		case String:
			return cvtIntString
		}

	case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
		switch dst.Kind() {
		case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
			return cvtUint
		case Float32, Float64:
			return cvtUintFloat
		case String:
			return cvtUintString
		}

	case Float32, Float64:
		switch dst.Kind() {
		case Int, Int8, Int16, Int32, Int64:
			return cvtFloatInt
		case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
			return cvtFloatUint
		case Float32, Float64:
			return cvtFloat
		}

	case Complex64, Complex128:
		switch dst.Kind() {
		case Complex64, Complex128:
			return cvtComplex
		}

	case String:
		if dst.Kind() == Slice && dst.Elem().PkgPath() == "" {
			switch dst.Elem().Kind() {
			case Uint8:
				return cvtStringBytes
			case Int32:
				return cvtStringRunes
			}
		}

	case Slice:
		if dst.Kind() == String && src.Elem().PkgPath() == "" {
			switch src.Elem().Kind() {
			case Uint8:
				return cvtBytesString
			case Int32:
				return cvtRunesString
			}
		}
		// “x是片，T是指向数组类型的指针，
		// 片和数组类型具有相同的元素类型。”
		if dst.Kind() == Pointer && dst.Elem().Kind() == Array && src.Elem() == dst.Elem().Elem() {
			return cvtSliceArrayPtr
		}

	case Chan:
		if dst.Kind() == Chan && specialChannelAssignability(dst, src) {
			return cvtDirect
		}
	}

	// dst和src具有相同的基础类型。
	if haveIdenticalUnderlyingType(dst, src, false) {
		return cvtDirect
	}

	// dst和src是具有相同基础基类型的未定义指针类型。
	if dst.Kind() == Pointer && dst.Name() == "" &&
		src.Kind() == Pointer && src.Name() == "" &&
		haveIdenticalUnderlyingType(dst.Elem().common(), src.Elem().common(), false) {
		return cvtDirect
	}

	if implements(dst, src) {
		if src.Kind() == Interface {
			return cvtI2I
		}
		return cvtT2I
	}

	return nil
}

// makeInt返回一个类型为t的值，该值等于位（可能被截断），
// 其中t是有符号或无符号int类型。
func makeInt(f flag, bits uint64, t Type) Value {
	typ := t.common()
	ptr := unsafe_New(typ)
	switch typ.size {
	case 1:
		*(*uint8)(ptr) = uint8(bits)
	case 2:
		*(*uint16)(ptr) = uint16(bits)
	case 4:
		*(*uint32)(ptr) = uint32(bits)
	case 8:
		*(*uint64)(ptr) = bits
	}
	return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
}

// makeFloat返回一个t类型的值，该值等于v（可能被截断为float32），
// 其中t是float32或float64类型。
func makeFloat(f flag, v float64, t Type) Value {
	typ := t.common()
	ptr := unsafe_New(typ)
	switch typ.size {
	case 4:
		*(*float32)(ptr) = float32(v)
	case 8:
		*(*float64)(ptr) = v
	}
	return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
}

// makeFloat返回一个类型为t等于v的值，其中t是float32类型。
func makeFloat32(f flag, v float32, t Type) Value {
	typ := t.common()
	ptr := unsafe_New(typ)
	*(*float32)(ptr) = v
	return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
}

// makeComplex返回一个t类型的值，该值等于v（可能被截断为complex64），
// 其中t是complex64或complex128类型。
func makeComplex(f flag, v complex128, t Type) Value {
	typ := t.common()
	ptr := unsafe_New(typ)
	switch typ.size {
	case 8:
		*(*complex64)(ptr) = complex64(v)
	case 16:
		*(*complex128)(ptr) = v
	}
	return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
}

func makeString(f flag, v string, t Type) Value {
	ret := New(t).Elem()
	ret.SetString(v)
	ret.flag = ret.flag&^flagAddr | f
	return ret
}

func makeBytes(f flag, v []byte, t Type) Value {
	ret := New(t).Elem()
	ret.SetBytes(v)
	ret.flag = ret.flag&^flagAddr | f
	return ret
}

func makeRunes(f flag, v []rune, t Type) Value {
	ret := New(t).Elem()
	ret.setRunes(v)
	ret.flag = ret.flag&^flagAddr | f
	return ret
}

// 对于转换类，这些转换函数由convertOp 
// 返回。例如，第一个函数cvtInt，
// 接受带符号整数类型的任何值v，并将转换后的值
// 返回给类型t，其中t是任何带符号或无符号整数类型。简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体中文：简体简体简体中文：简体中文：简体中文：简体简体简体简体简体简体简体简体简体简体简体简体简体简体简体简体简体简体简体简体简体这两种类型都有基础类型float32。

func cvtInt(v Value, t Type) Value {
	return makeInt(v.flag.ro(), uint64(v.Int()), t)
}

func cvtUint(v Value, t Type) Value {
	return makeInt(v.flag.ro(), v.Uint(), t)
}

func cvtFloatInt(v Value, t Type) Value {
	return makeInt(v.flag.ro(), uint64(int64(v.Float())), t)
}

func cvtFloatUint(v Value, t Type) Value {
	return makeInt(v.flag.ro(), uint64(v.Float()), t)
}

func cvtIntFloat(v Value, t Type) Value {
	return makeFloat(v.flag.ro(), float64(v.Int()), t)
}

func cvtUintFloat(v Value, t Type) Value {
	return makeFloat(v.flag.ro(), float64(v.Uint()), t)
}

func cvtFloat(v Value, t Type) Value {
	if v.Type().Kind() == Float32 && t.Kind() == Float32 {
		// 这避免了转换为float64并返回，这将
		// 将信令NaN转换为安静的NaN。见第36400期。
		return makeFloat32(v.flag.ro(), *(*float32)(v.ptr), t)
	}
	return makeFloat(v.flag.ro(), v.Float(), t)
}

// convertOp:complexXX->complexXX 
func cvtComplex(v Value, t Type) Value {
	return makeComplex(v.flag.ro(), v.Complex(), t)
}

// convertOp:intXX->string 
func cvtIntString(v Value, t Type) Value {
	s := "\uFFFD"
	if x := v.Int(); int64(rune(x)) == x {
		s = string(rune(x))
	}
	return makeString(v.flag.ro(), s, t)
}

// convertOp:uintXX->string 
func cvtUintString(v Value, t Type) Value {
	s := "\uFFFD"
	if x := v.Uint(); uint64(rune(x)) == x {
		s = string(rune(x))
	}
	return makeString(v.flag.ro(), s, t)
}

// convertOp:[]字节->字符串
func cvtBytesString(v Value, t Type) Value {
	return makeString(v.flag.ro(), string(v.Bytes()), t)
}

// convertOp:[]字节
func cvtStringBytes(v Value, t Type) Value {
	return makeBytes(v.flag.ro(), []byte(v.String()), t)
}

// 
func cvtRunesString(v Value, t Type) Value {
	return makeString(v.flag.ro(), string(v.runes()), t)
}

func cvtStringRunes(v Value, t Type) Value {
	return makeRunes(v.flag.ro(), []rune(v.String()), t)
}

// convertOp:[]T->*[N]T 
func cvtSliceArrayPtr(v Value, t Type) Value {
	n := t.Elem().Len()
	if n > v.Len() {
		panic("reflect: cannot convert slice with length " + itoa.Itoa(v.Len()) + " to pointer to array with length " + itoa.Itoa(n))
	}
	h := (*unsafeheader.Slice)(v.ptr)
	return Value{t.common(), h.Data, v.flag&^(flagIndir|flagAddr|flagKindMask) | flag(Pointer)}
}

// convertOp:directcopy 
func cvtDirect(v Value, typ Type) Value {
	f := v.flag
	t := typ.common()
	ptr := v.ptr
	if f&flagAddr != 0 {
		// 间接可变单词-复制
		c := unsafe_New(t)
		typedmemmove(t, c, ptr)
		ptr = c
		f &^= flagAddr
	}
	return Value{t, ptr, v.flag.ro() | f} // v.flag。ro（）| f==f？
}

// convertOp:concrete->interface 
func cvtT2I(v Value, typ Type) Value {
	target := unsafe_New(typ.common())
	x := valueInterface(v, false)
	if typ.NumMethod() == 0 {
		*(*any)(target) = x
	} else {
		ifaceE2I(typ.(*rtype), x, target)
	}
	return Value{typ.common(), target, v.flag.ro() | flagIndir | flag(Interface)}
}

// convertOp:interface->interface 
func cvtI2I(v Value, typ Type) Value {
	if v.IsNil() {
		ret := Zero(typ)
		ret.flag |= v.flag.ro()
		return ret
	}
	return cvtT2I(v.Elem(), typ)
}

// /运行时
func chancap(ch unsafe.Pointer) int
func chanclose(ch unsafe.Pointer)
func chanlen(ch unsafe.Pointer) int

// 注意：下面的一些noescape注释在技术上是谎言，但在这个包的上下文中是安全的。像chansend 
// 和mapassign这样的函数不会转义引用对象，但可以转义引用对象指向的任何内容（它们做引用对象的浅拷贝）。
// 在这个包中是安全的，因为referent只能指向一个值可能指向的对象，而这个值总是在堆中（由于ValueOf中的escapes（）调用）。go:noescape-

func chanrecv(ch unsafe.Pointer, nb bool, val unsafe.Pointer) (selected, received bool)

func chansend(ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool

func makechan(typ *rtype, size int) (ch unsafe.Pointer)
func makemap(t *rtype, cap int) (m unsafe.Pointer)

// go:noescape-
func mapaccess(t *rtype, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer)

// go:noescape-
func mapaccess_faststr(t *rtype, m unsafe.Pointer, key string) (val unsafe.Pointer)

// go:noescape-
func mapassign(t *rtype, m unsafe.Pointer, key, val unsafe.Pointer)

// go:noescape-
func mapassign_faststr(t *rtype, m unsafe.Pointer, key string, val unsafe.Pointer)

// go noescape-
func mapdelete(t *rtype, m unsafe.Pointer, key unsafe.Pointer)

// go noescape-
func mapdelete_faststr(t *rtype, m unsafe.Pointer, key string)

// go go noescape-
func mapiterinit(t *rtype, m unsafe.Pointer, it *hiter)

func mapiterkey(it *hiter) (key unsafe.Pointer)

func mapiterelem(it *hiter) (elem unsafe.Pointer)

func mapiternext(it *hiter)

func maplen(m unsafe.Pointer) int

// call调用fn，其中堆栈参数的“stackArgsSize”字节位于stackArgs，寄存器参数位于regArgs。frameSize是
// 调用将保留的堆栈空间总量，因此此
// 应包含足够的空间，以便在抢占的情况下将寄存器参数溢出到堆栈中。
// 
// 在fn返回后，调用将StackArgSize stackRetOffset结果字节
// 在返回前复制回stackArgs+stackRetOffset，用于堆栈上传递的任何返回
// 值。基于寄存器的返回值将在相同的regArgs结构中找到
// 。
// 
// regArgs还必须准备适当的返回位图
// 指示哪些寄存器将包含指针值返回值。
// 此位图的目的是在从reflectcall返回并实际使用它们之间保持指针对GC可见。
// 
// 如果从堆栈中复制结果字节，调用方必须将
// 参数帧类型作为stackArgsType传递，以便调用方在复制过程中执行适当的
// 写屏障。
// 
// 传递给调用的参数不转义。该类型仅用于
// 非常有限的调用被调用方，stackArgs被复制，regArgs仅用于调用帧中的
// 。
// go:noescape 
// go:linkname调用运行时。reflectcall 
func call(stackArgsType *rtype, f, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)

func ifaceE2I(t *rtype, src any, dst unsafe.Pointer)

// memmove将大小字节从src复制到dst。不使用写屏障。
// go:noescape 
func memmove(dst, src unsafe.Pointer, size uintptr)

// typedmemmove将类型t的值从src复制到dst。
// go:noescape 
func typedmemmove(t *rtype, dst, src unsafe.Pointer)

// typedmemmovepartial与typedmemmove类似，但假设
// dst和src将字节指向值中，并且只复制大小字节。
// go:noescape 
func typedmemmovepartial(t *rtype, dst, src unsafe.Pointer, off, size uintptr)

// typedmemclr将类型t的ptr处的值置零。
// go:noescape 
func typedmemclr(t *rtype, ptr unsafe.Pointer)

// TYPEDMEMCLRPROTIAL与类型DMEMCLR类似，但假设
// dst将字节清除到值中，并且只清除大小为字节的字节。
// go:noescape 
func typedmemclrpartial(t *rtype, ptr unsafe.Pointer, off, size uintptr)

// typedslicecompy将一段elemType值从src复制到dst，
// 返回复制的元素数。
// go:noescape 
func typedslicecopy(elemType *rtype, dst, src unsafeheader.Slice) int

// go:noescape 
func typehash(t *rtype, p unsafe.Pointer, h uintptr) uintptr

func verifyNotInHeapPtr(p uintptr) bool

// 标记值x转义的伪注释，
// 用于反射代码非常聪明以致编译器无法遵循的情况。
func escapes(x any) {
	if dummy.b {
		dummy.x = x
	}
}

var dummy struct {
	b bool
	x any
}
